在两次调用app.processEvents()之前,qsplashscreen无法正确显示

时间:2019-01-19 13:40:53

标签: python pyqt4 qsplashscreen

PyQT4.11
Python 2.7

我一直试图创建一个初始屏幕,以在选择特定选项卡时显示加载消息。调用app.processEvents()时,显示的是灰色框而不是图像,但是如果在调用第一个函数后添加第二个app.processEvents(),则显示正确的图像,直到启动完成时为止。

我一直在尝试睡眠定时器,重新粉刷,更新,关闭和重新显示选项卡和Tabwidget并产生不同的结果,在极少数情况下,它会起作用,但通常不会起作用。谁能阐明我所缺少的东西?

import sys
from PyQt4 import QtCore, QtGui

class splashTest(QtGui.QDialog):
    def __init__(self, parent=None):
        super(splashTest, self).__init__(parent)

        self.setGeometry(000,000,800,400)
        self.tabWidget = QtGui.QTabWidget(self)
        self.tabWidget.setGeometry(QtCore.QRect(0, 0, 500, 500))
        self.tabWidget.setObjectName("tabWidget")
        self.tab1 = QtGui.QWidget()
        self.tab2 = QtGui.QWidget()
        self.tab3 = QtGui.QWidget()

        self.tabWidget.addTab(self.tab1, "tab1")
        self.tabWidget.addTab(self.tab2, "tab2")
        self.tabWidget.addTab(self.tab3, "Click Me")

        self.tabWidget.setCurrentIndex(1)

        self.tabWidget.currentChanged.connect(self.whichTabIsSelected)


def whichTabIsSelected(self):
    if self.tabWidget.currentIndex() == 2:
        splash_pix = QtGui.QPixmap('splash.png')
        splash = QtGui.QSplashScreen(splash_pix, QtCore.Qt.WindowStaysOnTopHint)
        splash.setMask(splash_pix.mask())
        splash.show()
        app.processEvents()
        self.timeConsumingFunction()
        app.processEvents() 
        self.timeConsumingFunction()

        splash.finish(self.tabWidget)

    else:
        pass

def timeConsumingFunction(self):
    b = 0
    for a in range(100000000):
        b += a
    print (b)


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

1 个答案:

答案 0 :(得分:1)

问题是您正在阻止线程的GUI的主线程中运行繁重的任务,这会导致窗口冻结,并且您正在使用QApplication::processEvents()(而不是正确的解决方案)强制进行更新是要在另一个线程上执行该任务。

import sys
from PyQt4 import QtCore, QtGui
import threading

class splashTest(QtGui.QDialog):
    finished = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(splashTest, self).__init__(parent)

        self.setGeometry(000,000,800,400)
        self.tabWidget = QtGui.QTabWidget(self)
        self.tabWidget.setGeometry(QtCore.QRect(0, 0, 500, 500))
        self.tabWidget.setObjectName("tabWidget")
        self.tab1 = QtGui.QWidget()
        self.tab2 = QtGui.QWidget()
        self.tab3 = QtGui.QWidget()

        self.tabWidget.addTab(self.tab1, "tab1")
        self.tabWidget.addTab(self.tab2, "tab2")
        self.tabWidget.addTab(self.tab3, "Click Me")

        self.tabWidget.setCurrentIndex(1)
        self.tabWidget.currentChanged.connect(self.whichTabIsSelected)

    @QtCore.pyqtSlot(int)
    def whichTabIsSelected(self, index):
        if index == 2:
            splash_pix = QtGui.QPixmap('splash.png')
            splash = QtGui.QSplashScreen(self, splash_pix, QtCore.Qt.WindowStaysOnTopHint)
            splash.setMask(splash_pix.mask())
            splash.show()
            for _ in range(2):
                loop = QtCore.QEventLoop()
                self.finished.connect(loop.quit)
                threading.Thread(target=self.timeConsumingFunction).start()
                loop.exec_()
            splash.finish(self.tabWidget)
            splash.close()

    def timeConsumingFunction(self):
        b = 0
        for a in range(100000000):
            b += a
        print (b)
        self.finished.emit()


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