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

时间:2017-11-15 00:56:00

标签: python multithreading pyside python-multithreading

我正在尝试在我的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。 (之前我问过这个问题,但是没有得到任何答案或评论以及低评价,所以我删除了它并再次提出问题)

1 个答案:

答案 0 :(得分:1)

虽然python提供了几种通过线程执行任务的方法,但这些方法不一定符合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_())