2014-01-12 58 views
4

因此,在我的應用程序中,我創建了一個QtCore.QTimer對象,然後調用其上的singleShot方法在60秒後喚起一個函數。現在,在任何給定的時間點,如果我需要再次調用singleShot方法並阻止以前的singleShot方法生效(即阻止其調用傳遞給它的調用方,如果第二次singleShot是在前60秒之前調用),我需要做什麼?我如何'殺死'以前的QTimer並完全忘記它,只能使用當前的QTimer如何在PyQt4中殺死單個QtCore.QTimer?

有人可以幫我解決這個問題嗎?

這裏只是一個示例代碼:

def main(): 
    q = QtCore.QTimer() 
    q.singleShot(4000, print_hello) 
    q.killTimer(id)  ##how can I get the value of 'id' so that print_hello() is not called before the end of the 4 seconds? 

def print_hello(): 
    print 'hello' 

感謝

+1

是否有必要創建第二個'QTimer'如果已經存在一個? –

+0

@BedingedFingers謝謝!相應地編輯說明...可以請看看它是否更有意義? – gravetii

+0

現在它更混亂了,早些時候更好。 ;) –

回答

9

問題是QTimer.singleShot()未返回對QTimer的引用。無論如何,我不知道獲得定時器ID,所以你可以使用這種方法殺死它。但是,您可以將一個正常的QTimer實例化並使其成爲單次計時器(這不是您提供的代碼中所做的操作,在QTimer的實例上調用singleShot會創建一個您無權訪問的QTimer。 )

但是,一切都不會丟失。您可以創建一個正常的QTimer並使用setSingleShot(True)將其轉換爲單次計時器。如果你想中止定時器,這允許你調用stop()方法。請參閱下面的代碼示例,在3秒的超時時間內完成您所需的操作。您可以快速連續按下按鈕多次,並在停止後3秒鐘打印一次「hello」。如果你推一次,等待4秒鐘,然後再次推,它當然會打印兩次!

希望有幫助!

import sys 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 


class MyApp(QWidget): 
    def __init__(self,*args,**kwargs): 
     QWidget.__init__(self,*args,**kwargs) 
     self.current_timer = None 
     self.layout = QVBoxLayout(self) 
     self.button = QPushButton('start timer') 
     self.button.clicked.connect(self.start_timer) 
     self.layout.addWidget(self.button) 

    def start_timer(self): 
     if self.current_timer: 
      self.current_timer.stop() 
      self.current_timer.deleteLater() 
     self.current_timer = QTimer() 
     self.current_timer.timeout.connect(self.print_hello) 
     self.current_timer.setSingleShot(True) 
     self.current_timer.start(3000) 

    def print_hello(self): 
     print 'hello' 


# Create QApplication and QWidget 
qapp = QApplication(sys.argv) 
app = MyApp() 
app.show() 
qapp.exec_() 
+0

謝謝,那就是我一直在尋找的! – gravetii

1

如果第二QTimer的創作是完全必要那麼你的做法是不夠體面。你可以做什麼創建一個功能或類,這樣的簿記。您可以使用QBasicTimer。文檔:

QTimer類提供了一個高級編程接口,帶有單次定時器和定時器信號,而不是事件。還有一個比QTimer更輕量級的QBasicTimer類,比直接使用計時器ID更笨拙。

如果您想完全擺脫current_timer那麼我建議您撥打current_timer.deleteLater函數。確保在您撥打此功能後立即爲其指定一個新的QTimerdel /將其刪除del current_timer或者如果您稍後引用它的任何屬性,將會引發類似C++ object not found的錯誤。

+0

謝謝,雖然我仍然不完全確定要做什麼!我想我必須更好地閱讀Qtimers的文檔。爲了簡單起見,如果我有一個在T秒之後調用函數的singleShot QTimer,在t gravetii

1

建立在@three_pineapples's answer,並簡化了一些代碼。
每按一次按鈕就不需要創建新的QTimer,只需在現有定時器上調用.start(),它就會停止並重新啓動。

查看PyQt4 documentation for QTimer.start()

import sys 

from PyQt4.QtCore import QTimer 
from PyQt4.QtGui import (
    QApplication, 
    QWidget, 
    QVBoxLayout, 
    QPushButton, 
) 

class MyApp(QWidget): 
    def __init__(self,*args,**kwargs): 
     QWidget.__init__(self,*args,**kwargs) 

     self.layout = QVBoxLayout(self) 

     self.button = QPushButton('Start timer') 
     self.button.clicked.connect(self.start_timer) 

     self.layout.addWidget(self.button) 

     self.timer = QTimer() 
     self.timer.timeout.connect(self.hello) 
     self.timer.setSingleShot(True) 

    def start_timer(self): 
     self.timer.start(3000) 

    def hello(self): 
     print('Hello!') 

# Create QApplication and QWidget 
qapp = QApplication(sys.argv) 
app = MyApp() 
app.show() 
qapp.exec_() 
-1
import sys 

from PyQt4.QtCore import QTimer 
from PyQt4.QtGui import (
QApplication, 
QWidget, 
QVBoxLayout, 
QPushButton,) 

class MyApp(QWidget): 

    def __init__(self,*args,**kwargs): 
     QWidget.__init__(self,*args,**kwargs) 

     self.layout = QVBoxLayout(self) 

     self.button = QPushButton('Start timer') 
     self.button.clicked.connect(self.start_timer) 

     self.button1 = QPushButton('Stop timer') 
     self.button1.clicked.connect(self.stop_timer) 

     self.layout.addWidget(self.button) 
     self.layout.addWidget(self.button1) 
     self.timer = QTimer() 
     self.timer.timeout.connect(self.hello) 
     self.timer.setSingleShot(False) 


    def start_timer(self): 
     self.timer.start(1000) 

    def stop_timer(self):  
     self.timer.stop() 
     print('timer stop') 

    def hello(self): 
     b=1 
     print(a) 
     a.append(b) 
     print(a) 
     if len(a) == 5: 
      self.timer.stop() 
      print('timer stop') 


a=[] 
# Create QApplication and QWidget 
qapp = QApplication(sys.argv) 
app = MyApp() 
app.show() 
qapp.exec_() 
+0

不是最好的,但你可以得到一些想法如何停止qtimer – fLY

+1

請給你的答案添加一些解釋。只有代碼的答案通常是不被接受的。 – GurV

+0

使用方法self.timer.stop()來殺死你的計時器。它同時適用於self.timer.setSingleShot(True)和self.timer.setSingleShot(False)。在我的例子中,我創建了一個按鈕來停止計時器和if語句。 – fLY