如何在进入Qt事件循环后自动执行方法?

发布于 2024-11-13 07:48:56 字数 187 浏览 3 评论 0原文

我想执行一个只能在显示 QApplication 后调用的方法,即当它进入其主事件循环 exec_() 时。我是 Qt4 的新手(使用 PyQt4):我希望有一个类似 on_start() 的回调,但没有找到。 我需要创建一个线程或计时器吗?或者 API 中是否已经包含了一些回调?

I would like to execute a method which can only be called once my QApplication is displayed, i.e. when it has entered its main event loop exec_(). I'm new to Qt4 (using PyQt4): i was hoping to have a on_start()-like callback, but didn't find one.
Do i need to create a thread or a timer? Or is there some callback included in the API already?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

猫七 2024-11-20 07:48:56

您可以为此使用单次计时器,如以下简单脚本所示:

import sys
from PyQt4 import QtGui, QtCore

app = QtGui.QApplication(sys.argv)

def on_start():
    print(' in event loop!')
    print(' telling app to exit ...')
    app.exit(123)

QtCore.QTimer.singleShot(0, on_start)
print('About to enter event loop')
rc = app.exec_()
print('All done - returned %d' % rc)

当您运行此脚本时,您应该看到

About to enter event loop
 in event loop!
 telling app to exit ...
All done - returned 123

You can use a single-shot timer for this, as in the following simple script:

import sys
from PyQt4 import QtGui, QtCore

app = QtGui.QApplication(sys.argv)

def on_start():
    print(' in event loop!')
    print(' telling app to exit ...')
    app.exit(123)

QtCore.QTimer.singleShot(0, on_start)
print('About to enter event loop')
rc = app.exec_()
print('All done - returned %d' % rc)

when you run this, you should see

About to enter event loop
 in event loop!
 telling app to exit ...
All done - returned 123
无敌元气妹 2024-11-20 07:48:56

我以前没有使用过 Qt,所以我可能是错的,但我想你可以将 on_start() 方法绑定到 ApplicationActivate 事件,并设置一个标志在您的 on_start() 方法内部,以便代码仅在第一次运行,而不会在程序执行期间触发 ApplicationActivate 事件时运行。

另一方面,如果 on_start() 方法将由多个线程调用,您可能需要使用线程特定的标志。我自己没有做过太多多线程处理,所以我不确定它的具体细节是什么,或者它有多简单/复杂。

I haven't used Qt before, so I might be wrong on this, but I imagine you could bind your on_start() method to the ApplicationActivate event, and set a flag from inside your on_start() method so that the code would only be run that very first time and not any other times the ApplicationActivate event is triggered during execution of your program.

On the other hand if the on_start() method would be called by multiple threads, you might want to use thread-specific flags. Haven't done much multithreading myself, so I'm not sure of what the specifics for that would be, or how simple/complicated it would be.

水染的天色ゝ 2024-11-20 07:48:56

现在我选择以这种方式使用 QThread:

class MyThread(QtCore.QThread):
    def run(self):
    ''' reinplemented from parent '''
        # make thread sleep to make sure
        # QApplication is running before doing something
        self.sleep(2)
        do_something()

class MyWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.attr = 'foo'
        self.thread = MyThread(self)
        self.thread.start()

def main():
    app = QtGui.QApplication(sys.argv)
    w = MyWidget()
    w.show()
    sys.exit(app.exec_())

它可以满足我的目的,因为我的(真实)代码中的线程实际上在 X 显示中查找应用程序窗口,并且会尝试这样做,直到找到它为止。但除此之外,这并不是解决问题的优雅方法。
如果在进入事件循环时 QApplication 发出一个信号,那就更好了。 JAB 提出了 Qt.ApplicationActivate 但它似乎不是由 QApplication 发出的,即使是,因为 MyWidget() 没有实例化为 QApplication 的子级>,我不知道如何将信号从 app 传递到 w

在接受我的答案作为所选解决方案之前,我会等待更好的答案(如果有)。

For now i have chosen to use QThread this way:

class MyThread(QtCore.QThread):
    def run(self):
    ''' reinplemented from parent '''
        # make thread sleep to make sure
        # QApplication is running before doing something
        self.sleep(2)
        do_something()

class MyWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.attr = 'foo'
        self.thread = MyThread(self)
        self.thread.start()

def main():
    app = QtGui.QApplication(sys.argv)
    w = MyWidget()
    w.show()
    sys.exit(app.exec_())

It works for my purpose because my thread in my (real) code actually looks for the application window in X display and will try doing so until it finds it. But otherwise that's not an elegant way to solve the problem.
It would be nicer if there was a signal emitted by QApplication when entering the event-loop. JAB proposed the Qt.ApplicationActivate but it doesn't seem to be emitted by QApplication, and even if it was, because the MyWidget() is not instantiated as a child of QApplication, i wouldn't know how to pass the signal from app to w

I'll wait for a better answer, if any, before accepting my answer as the chosen solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文