我正在为 Python 使用 PyQt,并且正在构建一个图形用户界面。几周前我遇到了一个问题,我在 gui 模块之外有一个函数修改 gui 中的小部件(高级进度条、更新字符串等),并且这些修改没有反射(reflect)在 gui 中,直到函数更改完成运行。
对此的解决方案是在完成我想要的任何修改后简单地调用 app.processEvents(),这将立即更新窗口的图形。
但现在我想知道,有没有办法在每次提前窗口时都这样做?
假设我调用了一个函数来修改进度条,但是这个函数需要很长时间才能运行。在调用该函数和修改进度条之间,app 不处理任何事件。所以,在这段时间里,我拉出一个 Chrome 窗口(或其他任何东西),然后关闭它,我的 gui 窗口是空白的,只是灰色,直到 app.processEvents() 再次被调用。
PyQt 中的功能是否允许我检测窗口何时被带到所有当前窗口的前面?
请您参考如下方法:
你应该看看QThread .
线程允许您在worker 线程中运行长时间、复杂的任务,而background 线程保持 GUI 响应,例如更新 QProgressBar,确保它响应运动事件。
基本思路是这样的:
# load modules
import time
from PySide import QtCore, QtGui
# APPLICATION STUFF
# -----------------
APP = QtGui.QApplication([])
# THREADS
# -------
class WorkerThread(QtCore.QThread):
'''Does the work'''
def __init__(self):
super(WorkerThread, self).__init__()
self.running = True
def run(self):
'''This starts the thread on the start() call'''
# this goes over 1000 numbers, at 10 a second, will take
# 100 seconds to complete, over a minute
for i in range(1000):
print(i)
time.sleep(0.1)
self.running = False
class BackgroundThread(QtCore.QThread):
'''Keeps the main loop responsive'''
def __init__(self, worker):
super(BackgroundThread, self).__init__()
self.worker = worker
def run(self):
'''This starts the thread on the start() call'''
while self.worker.running:
APP.processEvents()
print("Updating the main loop")
time.sleep(0.1)
# MAIN
# ----
def main():
# make threads
worker = WorkerThread()
background = BackgroundThread(worker)
# start the threads
worker.start()
background.start()
# wait until done
worker.wait()
if __name__ == '__main__':
main()
你得到的输出是这样的,展示了它是如何轮流进行长计算和更新主循环的:
0
Updating the main loop
1
Updating the main loop
2
Updating the main loop
3
Updating the main loop
4
Updating the main loop
5
Updating the main loop
6
Updating the main loop
Updating the main loop7
8
Updating the main loop
9
这连同一个QFocusEvent覆盖应该允许你做任何你想做的事。但最好将更新 GUI 和运行所需的长线程分开。
至于重写 QFocusEvent,您可以执行以下操作:
def focusInEvent(self, event):
event.accept()
# insert your code here
如果您选择实现线程以避免 GUI 阻塞,您应该阅读 basics of threading (因为线程有很多细微差别,除非您知道它们的潜在陷阱)。
