如何让 QtGui 窗口在屏幕上出现时处理事件? [英] How to make QtGui window process events whenever it is brought forward on the screen?

查看:61
本文介绍了如何让 QtGui 窗口在屏幕上出现时处理事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将 PyQt 用于 Python,并且正在构建一个 gui.几周前我遇到了一个问题,我在 gui 模块之外有一个函数来修改 gui 中的小部件(高级进度条、更新字符串等),并且这些修改在 gui 中没有反映出来,直到函数完成更改完成运行.

I'm using PyQt for Python, and am building a gui. I had a problem a few weeks ago where I had a function outside of the gui module modifying widgets within the gui (advanced progress bar, updating strings, etc.), and those modifications were not reflected in the gui until the function that had made the changes finished running.

对此的解决方案是在进行我想要的任何修改后简单地调用 app.processEvents(),这将立即更新窗口的图形.

The solution to this was to simply call app.processEvents() after doing whatever modifications I wanted, which would immediately update the graphics of the window.

但现在我想知道,有没有办法在每次窗口前移时执行此操作?

But now I am wondering, is there a way to do this everytime the window is brought forward?

假设我调用了一个将修改进度条的函数,但该函数需要很长时间才能运行.在调用函数和修改进度条之间,app 不处理任何事件.所以,在这段时间里,我拉起一个 Chrome 窗口(或其他任何东西),然后关闭它,我的 gui 窗口是空白的,只是灰色的,直到 app.processEvents() 再次被调用.

Let's say I have called a function that will be modifying the progress bar, but this function takes quite a while to run. Inbetween calling the function, and the progress bar modification, the app processes no events. So, it during this time, I pull up a Chrome window (or anything else), and then close it, my gui window is blank, just gray, until app.processEvents() is called again.

PyQt 中的功能是否允许我检测窗口何时被带到所有当前窗口的前面?

Is ther functionality in PyQt that allows me to detect whenever the window is brought to the front of all current windows?

推荐答案

你应该看看 QThread.

线程允许您在 worker 线程中运行长而复杂的任务,而 后台 线程使 GUI 保持响应,例如更新 QProgressBar,确保它响​​应运动事件.

Threads allow you to run long, complicated tasks in a worker thread while a background thread keeps the GUI responsive, such as updating a QProgressBar, ensuring it responds to motion events.

基本思想是这样的:

# 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()

你得到的输出是这样的,显示了如何轮流进行长计算和更新主循环:

The output you get is something like this, showing how it takes turns at doing the long calculation and updating the main loop:

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 和运行所需的长线程分开.

This along with a QFocusEvent override should allow you to do whatever you wish. But it's better to separate updating the GUI and running your desired long thread.

至于覆盖 QFocusEvent,您可以执行以下操作:

As for overriding the QFocusEvent you can do something as follows:

def focusInEvent(self, event):
    event.accept()

    # insert your code here

如果您选择实现线程以避免 GUI 阻塞,您应该阅读 线程的基础知识(因为线程有很多细微差别,除非您了解它们的潜在缺陷).

And if you choose to implement threads to avoid GUI blocking, you should read about the basics of threading (as threads have a lot of nuances unless you know about their potential pitfalls).

这篇关于如何让 QtGui 窗口在屏幕上出现时处理事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆