Python + QT:如何使非GUI阻塞加载屏幕?

时间:2014-02-05 14:23:51

标签: python qt pyqt pyside

PySide的新手,所以可能在这里错误的基础知识。

我正在编写一个将启动的GUI应用程序,然后进行各种系统检查:

  • 检查硬件存在
  • 检查网络连接
  • 检查API连接

在整个过程中,它将通知用户当前正在做什么以及结果。

完成检查(并通过)后,它们将被带到程序初始屏幕。

目前,我一直试图在计时器中使用QApplication.processEvents运行检查:

if __name__ == '__main__':
    app = QApplication(sys.argv)
    rebadger = rebadger()
    rebadger.initUI()
    rebadger.show()

    tT = QTimer()
    tT.setSingleShot(False)
    tT.timeout.connect(QApplication.processEvents)
    tT.start(1000)

    rebadger.rebadgeObj.runChecks()

    sys.exit(app.exec_())

但是在检查完成之前,一切都会阻塞。

我已经查看了QThread文档,但我发现很难绕过事件逻辑(来自严格的PHP背景)

任何帮助勾勒出如何实现这一目标的方法都将非常感激。

2 个答案:

答案 0 :(得分:4)

也许QSplashScreen就是您所需要的:

if __name__ == '__main__':                                                                       

    import time                                                                                  
    app = QtGui.QApplication(sys.argv)                                                           
    splash = QtGui.QSplashScreen(QtGui.QPixmap('splash.png'))                                    
    splash.show()                                                                                
    for n in ("HW presence", "net connectivity", "API connectivity"):                            
        splash.showMessage("Check for {0}".format(n))                                            
        time.sleep(1)                                                                            
        app.processEvents()                                                                      
    mainWin = MainWindow()                                                                       
    splash.finish(mainWin)                                                                       
    mainWin.show()                                                                               
    sys.exit(app.exec_())                                                                        

答案 1 :(得分:1)

这是一个如何做你想做的事情的例子,检查QThread s用于长时间运行的后台处理,作为一个额外的你将有一个响应gui所以它适用于任何窗口而不仅仅是一个闪屏:

from PyQt4 import QtCore as core, QtGui as gui
import time

class MyProccess(core.QThread):

    newProgress = core.pyqtSignal(str)

    def __init__(self,i):
        super(MyProccess,self).__init__()
        self.id = i

    def run(self):
        for j in range(10):
            self.newProgress.emit('task %d at %d%%' % (self.id,j*10))
            time.sleep(0.2)            


class MySplash(gui.QSplashScreen):

    def __init__(self,mw):
        super(MySplash,self).__init__()
        layout = gui.QVBoxLayout(self)
        self.setLayout(layout)
        self.text = gui.QLabel(self)
        layout.addWidget(self.text) 
        self.setGeometry(300,300,100,0)          

        self.task1 = MyProccess(1)
        self.task2 = MyProccess(2)
        self.task3 = MyProccess(3)

        self.task1.newProgress.connect(self.showProgress)
        self.task2.newProgress.connect(self.showProgress)
        self.task3.newProgress.connect(self.showProgress)

        self.task1.finished.connect(self.task2.start)
        self.task2.finished.connect(self.task3.start)
        self.task3.finished.connect(mw.show)
        self.task3.finished.connect(self.hide)

    @core.pyqtSlot(str)
    def showProgress(self,msg):
        self.text.setText(msg)

    def event(self,ev):
        if type(ev) == gui.QShowEvent:
            self.task1.start()
        return super(MySplash,self).event(ev)

app = gui.QApplication([])

mw = gui.QMainWindow()

cw = gui.QWidget()
l = gui.QHBoxLayout()
cw.setLayout(l)
welcome = gui.QLabel()
welcome.setText('Welcome back!')
l.addWidget(welcome)

mw.setCentralWidget(cw)
mw.setGeometry(200,200,300,300)


w = MySplash(mw)
w.show()

app.exec_()