我正在寻找一种方法,在调用函数之前等待QWidget完全显示。我有两个窗口:父母和孩子。
父窗体是一个窗口,其中有一个调用openChild
的按钮,该按钮隐藏父级,显示子级,然后执行子级的主要功能busyFunc
:
from PyQt5 import QtCore, QtGui, QtWidgets
from Child import Child_Form
import sys
class Parent_Form(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.setupUi(self)
self.Child = Child_Form(self)
def setupUi(self, Parent):
Parent.setObjectName("Parent")
Parent.resize(400, 300)
self.nextWindow = QtWidgets.QPushButton(Parent)
self.nextWindow.setGeometry(QtCore.QRect(150, 120, 91, 31))
self.nextWindow.setObjectName("nextWindow")
self.retranslateUi(Parent)
QtCore.QMetaObject.connectSlotsByName(Parent)
def retranslateUi(self, Parent):
_translate = QtCore.QCoreApplication.translate
Parent.setWindowTitle(_translate("Parent", "Parent Window"))
self.nextWindow.setText(_translate("Parent", "Next Window"))
self.nextWindow.clicked.connect(self.openChild)
def openChild(self):
self.hide()
self.Child.show()
self.Child.busyFunc()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Parent_Form()
ex.show()
sys.exit(app.exec_())
子表单只有一个标签和一个带有文本编辑的滚动区域。
from PyQt5 import QtCore, QtGui, QtWidgets
class Child_Form(QtWidgets.QWidget):
def __init__(self, Parent_Form):
QtWidgets.QWidget.__init__(self)
self.setupUi(self)
self.parent = Parent_Form
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(400, 300)
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(20, 10, 61, 16))
self.label.setObjectName("label")
self.scrollArea = QtWidgets.QScrollArea(Form)
self.scrollArea.setGeometry(QtCore.QRect(20, 40, 361, 241))
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 359, 239))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.textEdit = QtWidgets.QTextEdit(self.scrollAreaWidgetContents)
self.textEdit.setGeometry(QtCore.QRect(0, 0, 361, 241))
self.textEdit.setObjectName("textEdit")
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Child Window"))
self.label.setText(_translate("Form", "Status:"))
def busyFunc(self):
for i in range(0, 1000000000):
pass
问题是调用busyFunc
时(实际功能是一个庞大的程序,所以我为了清楚起见省略了它。我使用循环模拟问题)。
父隐藏,但在busyFunc
完成之前,Child看起来像这样。
如何完全像这样加载子项然后执行busyFunc
?
答案 0 :(得分:1)
一种解决方案是在一段时间后通过计时器启动busyFunc函数。
def openChild(self):
self.hide()
self.Child.show()
QtCore.QTimer.singleShot(100, self.Child.busyFunc)
问题是在运行此函数时阻塞了接口,为了解决这个问题,建议在线程上运行该任务
class Thread(QtCore.QThread):
def __init__(self, parent=None):
QtCore.QThread.__init__(self, parent)
def run(self):
for i in range(0, 1000000000):
pass
class Child_Form(QtWidgets.QWidget):
def __init__(self, Parent_Form):
[...]
def busyFunc(self):
self.thread = Thread(self)
self.thread.start()
显然由于busyFunc的当前代码不与GUI交互,即不更新GUI的任何值,所以没有问题,但如果这个必须更新GUI的一些数据,它必须通过信号,不直接:
class Thread(QtCore.QThread):
signal = QtCore.pyqtSignal(str)
signal2 = QtCore.pyqtSignal(list)
def __init__(self, parent=None):
QtCore.QThread.__init__(self, parent)
def run(self):
self.signal.emit("start")
for i in range(0, 1000000000):
pass
self.signal.emit("finish")
self.signal2.emit([1, 2, 3, 4])
class Child_Form(QtWidgets.QWidget):
def __init__(self, Parent_Form):
[...]
def busyFunc(self):
self.thread = Thread(self)
self.thread.signal.connect(lambda text: self.textEdit.append(text))
self.thread.signal2.connect(lambda l: print(l))
self.thread.start()
class Parent_Form(QtWidgets.QWidget):
def __init__(self):
[...]
def openChild(self):
self.hide()
self.Child.show()
self.Child.busyFunc()