在 app.processEvents() 被调用两次之前,qsplashscreen 不会正确显示
qsplashscreen doesn't displays properly until app.processEvents() is called twice
PyQT4.11
Python2.7
我一直在尝试创建启动画面以在选择特定选项卡时显示加载消息。当调用 app.processEvents()
时,我会显示一个灰色框而不是图像,但是如果我在调用第一个函数后添加第二个 app.processEvents()
,则会显示正确的图像,直到启动完成时关闭。
我玩过睡眠定时器,重新绘制、更新、关闭和重新显示选项卡和选项卡小部件,结果好坏参半,在极少数情况下它会起作用,但通常不会。任何人都可以阐明我所缺少的东西吗?
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_())
问题是您 运行 主线程中的繁重任务阻塞了 GUI 的事件循环,这导致 window 冻结,您正在使用强制更新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_())
PyQT4.11
Python2.7
我一直在尝试创建启动画面以在选择特定选项卡时显示加载消息。当调用 app.processEvents()
时,我会显示一个灰色框而不是图像,但是如果我在调用第一个函数后添加第二个 app.processEvents()
,则会显示正确的图像,直到启动完成时关闭。
我玩过睡眠定时器,重新绘制、更新、关闭和重新显示选项卡和选项卡小部件,结果好坏参半,在极少数情况下它会起作用,但通常不会。任何人都可以阐明我所缺少的东西吗?
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_())
问题是您 运行 主线程中的繁重任务阻塞了 GUI 的事件循环,这导致 window 冻结,您正在使用强制更新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_())