2014-11-02 59 views
0
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上有所不同。但輸出是:在pyqt中使用計時器時奇怪的Python行爲

<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

我不知道你爲什麼會認爲這種行爲很奇怪。事件的順序就是這樣:

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) 

將使extimer父,因此保持它活着。但要做到這一點,QBasicTimer必須是QObject的子類 - 事實並非如此。

QBasicTimer.start()方法實際上是相同的:

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

我讀了'QBasicTimer'的文檔,但沒有關於實施隻字不提。我有點害怕,想到我應該在哪裏得到這個想法,還有什麼其他神祕的問題等着我。無論如何,這真的很奇怪,計時器在執行過程中被破壞。 – 2014-11-02 21:37:53

+0

@LeNoob。你不需要理解實現:我只是想解釋發生了什麼。但我仍然感到驚訝,你認爲這是「神祕」的。你是Python的新手,還是僅僅是PyQt?定時器在「執行的中間」沒有被破壞,因爲在事件循環開始之前什麼都不會發生(就事件而言)。無論如何,它是Qt計時器設計的一部分,它們在刪除時會自動停止。這對你來說似乎不合理嗎? – ekhumoro 2014-11-03 01:03:45

+0

我對Python比較陌生,對PyQt也是全新的:)我主要是Java開發人員,我明顯遇到了抓內部Python的問題,在這種情況下,垃圾收集是如何工作的(更不用說線程這裏了)。我試圖閱讀文檔和東西,但我根本無法理解它。 – 2014-11-29 23:53:10