Skip to main content
 首页 » 编程设计

python之如何让 QtGui 窗口在屏幕上显示时处理事件

2024年10月24日31mengfanrong

我正在为 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 (因为线程有很多细微差别,除非您知道它们的潜在陷阱)。