【问题标题】:In PyQt5, new parent is in a different Qthread after pop up QMessageBox在 PyQt5 中,弹出 QMessageBox 后,新父级在不同的 Qthread 中
【发布时间】:2018-11-10 11:55:31
【问题描述】:

这是 PyQt5 代码。我想倒计时 5 秒,每 1 秒更新一次。然后应用程序会弹出QMessageBox。
但由于QObject::setParent: Cannot set parent, new parent is in a different thread,点击QMessageBox上的按钮后它会关闭,
详细代码如下:

from PyQt5 import QtCore, QtGui, QtWidgets
import sys, time
from _thread import *

class ThreadClass(QtCore.QThread):
    # Create the signal
    sig = QtCore.pyqtSignal(int)

    def __init__(self, mw, parent=None):
        self.mw = mw
        self.mbox = QtWidgets.QMessageBox()
        super().__init__(parent)
        self.sig.connect(self.showtime)

    def showtime(self, t):
        self.mw.label.setText(str(t))

    def run(self):
        for t in range(5):
            self.sig.emit(t)
            time.sleep(1)
        self.mbox.about(QtWidgets.QMainWindow(), "Title", "Finished")

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(253, 181)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(90, 100, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(20, 20, 211, 16))
        self.label.setObjectName("label")
        self.tc = ThreadClass(self)
        self.pushButton.clicked.connect(lambda: self.tc.start())
        #self.pushButton.clicked.connect(lambda: start_new_thread(showtime, (self.label, )))
        MainWindow.setCentralWidget(self.centralwidget)


        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.pushButton.setText("Show")
        self.label.setText("Time")         

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    ex = Ui_MainWindow()
    w = QtWidgets.QMainWindow()
    ex.setupUi(w)
    w.show()
    sys.exit(app.exec_())

点击 QMessageBox 上的按钮和下面的错误消息后,应用程序将关闭。

QBasicTimer::stop: Failed. Possibly trying to stop from a different thread
QBasicTimer::stop: Failed. Possibly trying to stop from a different thread
QBasicTimer::stop: Failed. Possibly trying to stop from a different thread
QBasicTimer::stop: Failed. Possibly trying to stop from a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread

【问题讨论】:

    标签: python python-3.x pyqt5 qthread qmessagebox


    【解决方案1】:

    试试看:

    import sys   #, time
    from PyQt5 import QtCore, QtGui, QtWidgets
    from _thread import *
    
    class ThreadClass(QtCore.QThread):
        # Create the signal
        sig = QtCore.pyqtSignal(int)
        finish = QtCore.pyqtSignal()                # +++
    
        def __init__(self, mw, parent=None):
    #        self.mw = mw
    #        self.mbox = QtWidgets.QMessageBox()
            super().__init__(parent)
    #        self.sig.connect(self.showtime)
    
    #    def showtime(self, t):
    #        self.mw.label.setText(str(t))
    
        def run(self):
            for t in range(5):
                self.sig.emit(t)
                #time.sleep(1)
                QtCore.QThread.msleep(1000)
    
            self.finish.emit()                                             # +++
    #        self.mbox.about(QtWidgets.QMainWindow(), "Title", "Finished")
    
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.resize(253, 181)
            self.centralwidget = QtWidgets.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
    
            self.pushButton = QtWidgets.QPushButton(self.centralwidget)
            self.pushButton.setGeometry(QtCore.QRect(90, 100, 75, 23))
            self.pushButton.setObjectName("pushButton")
    
            self.label = QtWidgets.QLabel(self.centralwidget)
            self.label.setGeometry(QtCore.QRect(20, 20, 211, 16))
            self.label.setObjectName("label")
    
            self.tc = ThreadClass(self)
            self.pushButton.clicked.connect(lambda: self.tc.start())
            #self.pushButton.clicked.connect(lambda: start_new_thread(showtime, (self.label, )))
    
            self.tc.sig.connect(self.showtime)            # +++
            self.tc.finish.connect(self.finishTime)       # +++
    
    
            MainWindow.setCentralWidget(self.centralwidget)
    
    
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
            self.pushButton.setText("Show")
            self.label.setText("Time")         
    
    # +++
        def showtime(self, t):
            self.label.setText(str(t)) 
    
    # +++
        def finishTime(self):
            self.mbox = QtWidgets.QMessageBox()
            self.mbox.about(QtWidgets.QMainWindow(), "Title", "Finished")
    
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        w   = QtWidgets.QMainWindow()
        ex  = Ui_MainWindow()
        ex.setupUi(w)
        w.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 添加一些解释会使这个答案更有用。
    猜你喜欢
    • 2023-01-30
    • 2020-05-14
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多