2014-01-12 45 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