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 种不同类型的输出,其 timer 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
这种行为很让人困惑,究竟是什么原因导致了这种行为?变量名的改变是如何影响程序运行的?
2、解决方案
问题分析
问题的原因在于 Python 的垃圾回收机制在起作用。当我们创建第二个对象时,第一个对象的唯一引用就会被删除,然后第一个对象就会被垃圾回收。而第二个对象本身并不会被垃圾回收,因为事件循环阻止了函数返回。
解决方法
为了解决这个问题,我们需要确保第一个计时器对象在不再需要时被明确销毁。我们可以通过在 Example
类中添加一个 stopTimer()
方法来实现这一点,该方法可以停止计时器并将其从对象中移除。
class Example(QObject):
def timerEvent(self, event):
print "timer event, timer Id:", event.timerId()
def stopTimer(self):
if hasattr(self, "timer"):
self.timer.stop()
del self.timer
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
ex.stopTimer()
sys.exit(app.exec_())
代码示例
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 stopTimer(self):
if hasattr(self, "timer"):
self.timer.stop()
del self.timer
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
ex.stopTimer()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
运行这段代码,将输出如下结果:
<PyQt4.QtCore.QBasicTimer object at 0xb69b90>
<PyQt4.QtCore.QBasicTimer object at 0xb69c08>
timer event, timer Id: 33554433
timer event, timer Id: 1
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: 1
可以看到,已经得到了预期的输出,两个 timer 对象都有了自己的 timer id。