2014-11-02 3 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() 

이 코드에서는 타이머 ID가 다른 2 가지 종류의 출력을 볼 것으로 예상됩니다. 그러나 출력은 다음과 같습니다pyqt에서 타이머를 사용할 때의 이상한 파이썬 동작

<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 

무엇도 이상한 것은 그 I는 다음과 같이 두 번째 타이머 변수의 이름을 변경하는 경우 : 다음

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 

저는 파이썬을 이해하려고 노력하고 있습니다. 그리고 이것은 정말로 저를 혼란스럽게합니다. 이 문제의 원인은 무엇입니까? 변수의 이름이 프로그램을 어떻게 바꿀 수 있습니까?

답변

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_()) 

그래서 이것은 일반적인 파이썬 쓰레기 수거 일뿐입니다. 같은 이름의 두 번째 객체를 만들면 첫 번째 객체에 대한 유일한 참조가 제거되고 즉시 가비지 수집됩니다. 물론 이벤트 루프가 함수를 반환하지 못하게하므로 두 번째 객체 자체가 가비지 수집되지 않습니다

QBasicTimer에 대한 설명서를 읽지 않았다면이 줄이 :

timer.start(500, ex) 

ex에게 timer의 부모를 만들 것 때문에 살아 보관하십시오. 하지만 작동하려면 QBasicTimerQObject의 하위 클래스 여야합니다.이 하위 클래스는 그렇지 않습니다.

QBasicTimer.start() 방법이 실제로 동일합니다 :

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

나는 QBasicTimer''에 대한 문서를 읽을 수 있지만 구현에 대한 언급은 없습니다. 나는이 아이디어를 얻기 위해 어디에서 왔으며 다른 신비로운 문제들이 나를 기다리고 있는지를 생각해 보면 무서워. 어쨌든 정말 이상합니다. 타이머는 실행 중간에 파괴됩니다. –

+0

@LeNoob. 구현을 이해할 필요는 없습니다. 나는 지금 무슨 일이 일어나고 있는지 설명하려고했습니다. 그러나 나는 아직도 당신이 이것 중 하나가 "수수께끼"라고 생각한다는 것에 놀랐습니다. 파이썬이나 PyQt를 처음 접하십니까? 타이머는 이벤트 루프가 시작될 때까지 아무런 일도 일어나지 않기 때문에 "실행 중간"에서 파괴되지 않았습니다. 어떤 경우 든 Qt 타이머가 삭제 될 때 자동으로 멈추는 Qt 타이머 디자인의 일부입니다. 그게 너에게 합리적이지 않니? – ekhumoro

+0

필자는 Python에 비교적 익숙하고 PyQt에 처음으로 익숙하다. 나는 주로 자바 개발자이며, 파이썬의 내부 구조를 파악하는 데 문제가있다.이 경우 쓰레기 수거가 어떻게 작동하는지 (여기에서는 스레드를 언급하지 않는다). 나는 워드 프로세서 & 물건을 읽으려고했지만 단순히 이해할 수 없었다. –

관련 문제