在pyqt中使用计时器时出现奇怪的Python行为

时间:2014-11-02 14:13:23

标签: python pyqt

import sys

from PyQt4 import QtGui
from PyQt4.QtCore import QObject, QBasicTimer


class Example(QObject):

    def timerEvent(self, event):
        print "timer event, timer Id:", event.timerId()



def main():
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    timer = QBasicTimer()
    timer.start(500, ex) 
    print timer

    timer = QBasicTimer()
    timer.start(300, ex) 
    print timer

    sys.exit(app.exec_())

#Run it
main()

使用这段代码,我希望看到2种不同的输出,它们在计时器ID上有所不同。但输出是:

<PyQt4.QtCore.QBasicTimer object at 0xb69b90>
<PyQt4.QtCore.QBasicTimer object at 0xb69c08>
timer event, timer Id: 33554433
timer event, timer Id: 33554433
timer event, timer Id: 33554433
timer event, timer Id: 33554433
timer event, timer Id: 33554433
timer event, timer Id: 33554433

同样奇怪的是,如果我更改第二个计时器的变量名称,如下所示:

    timer = QBasicTimer()
    timer.start(500, ex) 
    print timer

    timer2 = QBasicTimer()
    timer2.start(300, ex) 
    print timer2

然后我得到了预期的结果:

<PyQt4.QtCore.QBasicTimer object at 0x17b3b90>
<PyQt4.QtCore.QBasicTimer object at 0x17b3c08>
timer event, timer Id: 16777218
timer event, timer Id: 1
timer event, timer Id: 16777218
timer event, timer Id: 16777218
timer event, timer Id: 1
timer event, timer Id: 16777218
timer event, timer Id: 1
timer event, timer Id: 16777218
timer event, timer Id: 16777218
timer event, timer Id: 1

我正在尝试理解Python,这真让我感到困惑。是什么导致了这种行为?变量的名称如何改变程序?

1 个答案:

答案 0 :(得分:1)

我不知道为什么你会认为这种行为很奇怪。事件的顺序就是这样:

ex = Example()
# timer(1) object is created
timer = QBasicTimer()
# ex object registers timer(1)
timer.start(500, ex) 
print timer

# timer(2) object is created
# timer(1) object is destroyed
# timer(1) destructor unregisters timer(1)
timer = QBasicTimer()
# ex object registers timer(2)
timer.start(300, ex) 
print timer

# event loop starts, 300ms later, timer(2) event is processed...
sys.exit(app.exec_())

所以这只是普通的python垃圾收集工作。创建具有相同名称的第二个对象将删除对第一个对象的唯一引用,该对象立即被垃圾收集。当然,第二个对象本身不会被垃圾收集,因为事件循环会阻止函数返回

如果您没有阅读QBasicTimer的文档,我想您可能已经考虑过这一行:

timer.start(500, ex)

会使ex成为timer的父级,从而使其保持活力。但要实现这一点,QBasicTimer必须是QObject的子类 - 它不是。{/ p>

QBasicTimer.start()方法实际上与此相同:

def start(self, msec, obj):
    self.stop()
    if obj is not None:
        self.id = obj.startImer(msec)