2017-06-16 54 views
0

我正在尋找一種方法,在調用函數之前等待QWidget完全顯示。我有兩個窗口:父母和孩子。Pyqt5等到窗口小部件可見爲止

母體形式是與調用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完成。

我怎樣才能讓孩子負載完全是這樣,然後執行busyFunc

+0

如果有什麼辦法可以讓我的問題更清楚,請說出來! – Jaitnium

+0

看到我的解決方案 – eyllanesc

回答

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() 
+0

謝謝你的深入解決方案!我會讓你知道結果如何。 – Jaitnium

+0

我試過你的解決方案,幾乎解決了我的問題。有什麼辦法從線程發出一個列表? – Jaitnium

+0

如果可以的話,我已經更新了顯示如何操作的代碼 – eyllanesc