我的道歉:
这似乎是以下情况的重复: PyQt - running a loop inside GUI
具有良好的解决方案和教程链接。
我的设置:
操作系统:Windows 10 ver1903
Python:3.7.4
PyQt5:5.13.0
我的问题:
PyQt5没有持续更新statusBar。 我在较大的应用程序中看到此问题。 我编写了此调试应用程序,以尝试更清楚地确定问题所在,并且再现了该问题:
import sys, time
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class statusdemo(QMainWindow):
def __init__(self, parent = None):
super(statusdemo, self).__init__(parent)
qpb = QPushButton("Debug")
qpb.clicked.connect(self.debug)
self.setCentralWidget(qpb)
self.statusBar = QStatusBar()
self.setWindowTitle("QStatusBar Debug")
self.setStatusBar(self.statusBar)
def wait(self, duration=2.0):
print(f"waiting for {duration}")
tstart = time.time()
while(True):
if duration < (time.time() - tstart):
break
def debug(self):
# self.statusBar.showMessage("Checkpoint 001", 2000)
self.statusBar.showMessage("Checkpoint 001")
# time.sleep(2)
self.wait()
# self.statusBar.showMessage("Checkpoint 002", 2000)
self.statusBar.showMessage("Checkpoint 002")
# time.sleep(2)
self.wait()
# self.statusBar.showMessage("Checkpoint 003", 2000)
self.statusBar.showMessage("Checkpoint 003")
# time.sleep(2)
self.wait()
# self.statusBar.showMessage("Completed debug()", 2000)
self.statusBar.showMessage("Completed debug()")
def main():
app = QApplication(sys.argv)
ex = statusdemo()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
已执行:单击“调试”按钮,并定期在状态栏中打印"Checkpoint ###"
2秒钟,最后以不确定的状态栏显示“ Completed debug()”。 / p>
实际:单击“调试”按钮,以cmd格式查看wait()
中的打印语句,但是直到"Checkpoint ###"
为止,我都没有看到"Completed debug()"
个更新
我现在似乎下一步就是尝试利用“ statusBar.messageChanged”信号,但是对于应该内置的东西来说感觉太高了。我想我丢失了显而易见但看不到的东西。
答案 0 :(得分:1)
您的示例不起作用,因为wait
函数中的while循环将阻止gui并阻止状态栏更新。有几种解决此问题的方法。如果状态栏更新以固定的间隔发生,则可以使用timer并将插槽连接到其timeout signal。但是,如果该插槽进行了一些繁重的计算,这仍然可能会阻塞gui-在这种情况下,您应该将计算移到工作线程中,并通过信号将更新发送回主线程(请参见here一个简单的例子)。再说一次,如果您只需要一种快速且肮脏的调试方法,则可以使用process-events临时强制gui更新。例如,您示例中的wait
函数可以这样工作:
def wait(self, duration=2.0):
qApp.processEvents() # clear current event queue
time.sleep(duration) # this will block gui updates
答案 1 :(得分:0)
尝试一下:
import sys, time
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class statusdemo(QMainWindow):
def __init__(self, parent = None):
super(statusdemo, self).__init__(parent)
self.msgs = ["Checkpoint 001", "Checkpoint 002", "Checkpoint 003", "Completed debug()"] # +
self.n = len(self.msgs) # +
self.i = 0 # +
qpb = QPushButton("Debug")
qpb.clicked.connect(self.debug)
self.setCentralWidget(qpb)
self.statusBar = QStatusBar()
self.setWindowTitle("QStatusBar Debug")
self.setStatusBar(self.statusBar)
self.timer = QTimer(self) # +
self.timer.setInterval(2000)
self.timer.timeout.connect(self.show_message)
def show_message(self):
self.statusBar.showMessage(self.msgs[self.i])
self.i += 1
if self.i == self.n:
self.timer.stop()
self.i = 0
def debug(self):
self.timer.start()
def main():
app = QApplication(sys.argv)
ex = statusdemo()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()