退出PyQt5应用程序后如何打破循环?

How to break a loop after exiting a PyQt5 application?

提问人:MWA 提问时间:11/6/2023 最后编辑:ekhumoroMWA 更新时间:11/7/2023 访问量:33

问:

import os
import sys
import pandas as pd
import cv2
import datetime
from pyzbar.pyzbar import decode
from PyQt5 import QtCore
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.uic import loadUi
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QDialog, QApplication, QLabel

class QR_Scan_Window(QDialog):
    def __init__(self):
        super(QR_Scan_Window, self).__init__()
        ui_path = os.path.dirname(os.path.abspath(__file__))
        loadUi(os.path.join(ui_path, "QR_Scan_Window.ui"), self)

    def display_image(self):
        self.cap = cv2.VideoCapture(0)
        self.qr_data = 0
        self.qr_type = 0

        while((self.cap.isOpened()) and (widget.currentIndex() == 0)):
            ret, frame = self.cap.read()

            # Decode QR codes from the frame
            self.decoded_objects = decode(frame)

            if(ret == True):
                self.display_frame(frame)
                # Loop through the detected QR codes
                for obj in self.decoded_objects:
                    self.qr_data = obj.data.decode('utf-8')
                    self.qr_type = obj.type

                    # Print the QR code data and type
                    print(f'Type: {self.qr_type}, Data: {self.qr_data}')
                # Jika QR Code telah terbaca, keluar loop
                if self.qr_type == "QRCODE":
                    break
                cv2.waitKey()
            else:
                print("return not found")

        if self.qr_type == "QRCODE":
            #self.goto_Camera_Window()
            pass

    def display_frame(self, img):
        qformat = QImage.Format_Indexed8

        if(len(img.shape) == 3):
            if(img.shape[2] == 4):
                qformat = QImage.Format_RGBA888
            else:
                qformat = QImage.Format_RGB888
        
        img = QImage(img, img.shape[1], img.shape[0], qformat)
        img = img.rgbSwapped()
        self.imgLabel.setPixmap(QPixmap.fromImage(img))
        self.imgLabel.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)

    # This function will be called when the window is closed
    def closeEvent(self, event):
        self.cap.release()
        cv2.destroyAllWindows()
        event.accept()  # Accept the close event

app = QApplication(sys.argv)

widget = QtWidgets.QStackedWidget()

qr_scan_window = QR_Scan_Window()

widget.addWidget(qr_scan_window)

widget.setFixedHeight(320)
widget.setFixedWidth(480)

widget.show()

qr_scan_window.display_image()

try:
    sys.exit(app.exec_())
except:
    print("Exiting")
    cv2.destroyAllWindows()

我想退出应用程序/窗口并断开函数中的循环,但不起作用。当我使用此代码并退出时,碰巧我的相机仍然打开并且循环函数仍在运行。帮我修复此代码:(display_imagecloseEventdisplay_image

python opencv 事件 pyqt5

评论

0赞 musicamante 11/6/2023
不能使用内部 while 循环来阻止 GUI 事件循环。您可能应该将其移动到单独的 QThread 中(它最终将使用信号与主线程交互,因为 UI 元素不是线程安全的)。然后,将告诉线程停止其循环(可能通过使用直接从调用线程设置的基本布尔值标志),等待线程完成,最后允许应用程序退出。closeEvent()
0赞 MWA 11/7/2023
我真的不明白该怎么做,你能告诉我怎么做吗?@musicamante
0赞 musicamante 11/7/2023
对不起,但是不,网络上已经有很多类似的资源(包括SO上),我强烈建议你花点时间,做适当的研究,在PyQt中使用QThread的单独线程,从最少的例子开始,这样你就可以开始了解它的基本行为,并最终在你的程序中实现它。

答: 暂无答案