QStatusBar.showMessage() 更新不一致
QStatusBar.showMessage() not updating consistently
我的道歉:
这似乎是以下内容的重复:
PyQt - running a loop inside GUI
哪个有好的解决方案和教程LINK。
我的设置:
OS: Windows 10 ver1903
Python: 3.7.4
PyQt5: 5.13.0
我的问题:
PyQt5 没有持续更新状态栏。
我在一个更大的应用程序中看到了这个问题。
我写了这个调试应用程序来尝试更清楚地识别问题,并且它已重现:
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()
预期: 单击 "Debug" 按钮,会看到 "Checkpoint ###"
周期性地在状态栏中打印 2 秒,最后无限期状态栏显示 "Completed debug()".
ACTUAL:点击"Debug"按钮,在cmd中看到wait()
的打印语句,但是我看到none的"Checkpoint ###"
更新到 "Completed debug()"
.
- 我尝试过天真地使用内置持续时间参数 statusBar.showMessage()。
- 我试过使用 time.sleep(2).
- 我已经尝试创建自己的等待方法,该方法不应像 sleep 那样暂停进程(以防妨碍)。
我正处于下一步似乎是尝试利用 "statusBar.messageChanged" 信号的地步,但这对于应该内置的东西来说感觉太多了。我想我'我遗漏了一些明显但看不到的东西。
试一试:
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()
您的示例不起作用,因为 wait
函数中的 while 循环将阻止 gui 并阻止状态栏更新。有几种不同的方法来处理这个问题。如果状态栏更新以固定的时间间隔发生,您可以使用 timer and connect a slot to its timeout signal. However, if the slot does some heavy calculations, this could still block the gui - in which case, you should move the calculations into a worker thread, and send the updates back to the main thread via signal (see for a simple example). Then again, if you only need a quick and dirty method for debugging, you could temporarily force gui updates using process-events。例如,您示例中的 wait
函数可以像这样工作:
def wait(self, duration=2.0):
qApp.processEvents() # clear current event queue
time.sleep(duration) # this will block gui updates
我的道歉:
这似乎是以下内容的重复: PyQt - running a loop inside GUI
哪个有好的解决方案和教程LINK。
我的设置:
OS: Windows 10 ver1903
Python: 3.7.4
PyQt5: 5.13.0
我的问题:
PyQt5 没有持续更新状态栏。 我在一个更大的应用程序中看到了这个问题。 我写了这个调试应用程序来尝试更清楚地识别问题,并且它已重现:
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()
预期: 单击 "Debug" 按钮,会看到 "Checkpoint ###"
周期性地在状态栏中打印 2 秒,最后无限期状态栏显示 "Completed debug()".
ACTUAL:点击"Debug"按钮,在cmd中看到wait()
的打印语句,但是我看到none的"Checkpoint ###"
更新到 "Completed debug()"
.
- 我尝试过天真地使用内置持续时间参数 statusBar.showMessage()。
- 我试过使用 time.sleep(2).
- 我已经尝试创建自己的等待方法,该方法不应像 sleep 那样暂停进程(以防妨碍)。
我正处于下一步似乎是尝试利用 "statusBar.messageChanged" 信号的地步,但这对于应该内置的东西来说感觉太多了。我想我'我遗漏了一些明显但看不到的东西。
试一试:
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()
您的示例不起作用,因为 wait
函数中的 while 循环将阻止 gui 并阻止状态栏更新。有几种不同的方法来处理这个问题。如果状态栏更新以固定的时间间隔发生,您可以使用 timer and connect a slot to its timeout signal. However, if the slot does some heavy calculations, this could still block the gui - in which case, you should move the calculations into a worker thread, and send the updates back to the main thread via signal (see wait
函数可以像这样工作:
def wait(self, duration=2.0):
qApp.processEvents() # clear current event queue
time.sleep(duration) # this will block gui updates