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

时间:2011-06-02 14:11:13

标签: python multithreading timer pyqt4 event-loop

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

3 个答案:

答案 0 :(得分:4)

您可以使用单次定时器,如下面的简单脚本:

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

答案 1 :(得分:0)

之前我没有使用过Qt,所以我可能错了,但我想你可以将on_start()方法绑定到ApplicationActivate事件,并在{{{ 1}}方法,这样代码只会在第一次运行,而不会在执行程序时触发on_start()事件。

另一方面,如果多个线程调用ApplicationActivate方法,您可能希望使用特定于线程的标志。我自己没有做太多的多线程,所以我不确定具体是什么,或者它有多简单/复杂。

答案 2 :(得分:0)

现在我选择以这种方式使用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

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