使用线程在 PySide 中创建加载显示

Creating loading display in PySide with threading

我试图在我的 pyside 程序的开头显示加载图形(现在只是一个标签),而另一个函数是 运行。完成后,它应该继续并加载主 GUI。到目前为止我有这个

from PySide import QtCore
from PySide import QtGui

class DoStuff:
    def __init__(self):
        pass

    def ReturnInformation(self):
        time.sleep(20)                              #Sleep to simulate processing time
        return "information"

class Main(QtGui.QWidget):
    def __init__(self):
        super(Main, self).__init__()
        self.initQ = queue.Queue()
        self.initthread = threading.Thread(target=self.InitThread)
        self.initthread.daemon = True
        self.initthread.start()

        self.setStyleSheet("background-color: black;")
        self.setCursor(QtCore.Qt.BlankCursor)

        self.loaddisplay = QtGui.QLabel(self)
        self.loaddisplay.move(20, 20)
        self.loaddisplay.setText("Loading...")
        self.show()

        self.initthread.join()
        self.MainDisplay()
        self.show()

    def InitThread(self):
        self.dostuff = DoStuff()


    def MainDisplay(self):
        self.display = QtGui.QLabel(self)
        self.display.setStyleSheet("font: 70pt Helvetica; color: white;")
        self.display.move(20, 20)
        self.display.setText(self.dostuff.ReturnInformation())

        self.manager = QtCore.QTimer(self)
        self.manager.timeout.connect(self.Update)
        self.manager.start(100000)

    def Update(self):                                                  #Update the information once in a while
        self.timedisplay.setText(self.dostuff.ReturnInformation())

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    GUI = Main()
    sys.exit(app.exec_())

问题是只显示加载图形,而从不显示 MainDisplay() 中的 GUI。我很确定这与我调用 show() 函数的方式有关。这是问题所在吗?我该如何解决?

另外,加载完成后如何删除加载标签?

P.S。 (我之前问过这个问题,但没有得到任何答案或评论,而且观点很低,所以我删除了它,然后再次提问)

虽然python提供了几种通过线程执行task的方式,但不一定符合Qt的规则,使用QThread等框架的工具是合适的:

class DoStuffThread(QtCore.QThread):
    displaySignal = QtCore.Signal(str)
    timeSignal = QtCore.Signal(str)

    def __init__(self, *args, **kwargs):
        QtCore.QThread.__init__(self, *args, **kwargs)

        self.timer = QtCore.QTimer()
        self.timer.moveToThread(self)
        self.timer.timeout.connect(self.onTimeout)
        self.stuff = DoStuff()

    def onTimeout(self):
        data = self.stuff.ReturnInformation()
        self.timeSignal.emit(data)

    def run(self):
        data = self.stuff.ReturnInformation()
        self.displaySignal.emit(data)
        self.timer.start(20000)
        loop = QtCore.QEventLoop()
        loop.exec_()


class DoStuff:
    def ReturnInformation(self):
        time.sleep(2)  # Sleep to simulate processing time
        return "information-{}".format(QtCore.QTime.currentTime().toString("hh:mm:ss"))


class Main(QtGui.QWidget):
    def __init__(self):
        super(Main, self).__init__()
        self.setStyleSheet("background-color: black;")
        self.setCursor(QtCore.Qt.BlankCursor)
        self.setLayout(QtGui.QVBoxLayout())

        self.loaddisplay = QtGui.QLabel(self)
        self.display = QtGui.QLabel(self)
        self.timedisplay = QtGui.QLabel(self)

        self.layout().addWidget(self.loaddisplay)
        self.layout().addWidget(self.display)
        self.layout().addWidget(self.timedisplay)

        self.thread = DoStuffThread(self)
        self.thread.displaySignal.connect(self.display.setText, QtCore.Qt.QueuedConnection)
        self.thread.timeSignal.connect(self.timedisplay.setText, QtCore.Qt.QueuedConnection)
        self.thread.start()

        self.loaddisplay.move(20, 20)
        self.loaddisplay.setText("Loading...")
        self.display.setStyleSheet("font: 70pt Helvetica; color: white;")
        self.display.move(20, 20)

    def closeEvent(self, event):
        self.thread.quit()
        QtGui.QWidget.closeEvent(self, event)


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    GUI = Main()
    GUI.show()
    sys.exit(app.exec_())