В PyQt5 новый родитель находится в другом Qthread после всплывающего QMessageBox
Это код PyQt5. Я хочу отсчитывать 5 секунд и обновлять каждую 1 секунду. Тогда приложение будет всплывать QMessageBox.
Но он будет закрыт после нажатия кнопки на QMessageBox из-за QObject::setParent: Cannot set parent, new parent is in a different thread
,
подробный код ниже:
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
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_())