使用“停止按钮”退出功能

时间:2016-06-26 08:24:54

标签: python qt pyqt4

所以我正在尝试创建一个计时器或排序,启动按钮启动计时器,我需要用停止按钮停止计时器然后记录时间...我似乎无法弄清楚如何一旦启动,就停止计时器功能。我试过if语句,disconnect()和其他许多人...... 我意识到qt中已经有一个计时器,但我试图通过这种方式弄明白。谢谢。

import sys
import time
from PyQt4 import QtCore, QtGui, uic

form_class = uic.loadUiType("/Users/Home/Desktop/Timer/timer.ui")[0]  


class MyWindowClass(QtGui.QMainWindow, form_class):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.startButton.clicked.connect(self.timer)

    def timer(self):
        timeL = 0
        self.stopButton.clicked.connect(False)
        while True:
            self.timeView.display(timeL)
            timeL = timeL + 1
            time.sleep(1)
            app.processEvents()


app = QtGui.QApplication(sys.argv)
myWindow = MyWindowClass(None)
myWindow.show()
app.exec_()

3 个答案:

答案 0 :(得分:2)

TL; DR:你在QElapsedTimer之后,而不是QTimer

操作系统已经在测量你的时间。你自己也不会做得更好。

“我试图通过这种方式弄明白” - 它不如使用QElapsedTimer那么准确,因为你假设你想要睡觉的时间已经过去了。这几乎不是真的:实际传递的时间量与sleep的参数不同。更糟糕的是,错误通常也是系统性的,因此随着时间的推移,您的时间积累会产生偏差并且会变得不那么准确。所以,不要这样做。这没有道理。也许你并没有告诉我们你正在尝试做什么:如果你问的是一个不起作用的特定解决方案,那么说明该解决方案应该是什么问题会有所帮助。 为什么你想弄清楚这个(错误的)方式?

Qt中有三种不同的计时器:

  1. QElapsedTimer就像秒表:它是操作系统测量时间流逝的一种界面。这是您应该用来衡量按钮点击之间经过了多长时间的课程。

  2. QTime就像一个挂钟:您可以通过currentTime()询问它的时间,并在两次读取时间之间取差异以获得经过的时间。仅在您需要知道绝对时间时才使用此课程,否则QElapsedTimer将为经过时间测量提供更好的分辨率。

  3. QTimer是超时的来源:它是一种定期调用代码的方法。这并不意味着用于测量时间,而只是让您的代码定期运行,例如当您希望刷新屏幕显示,或实现定期发出蜂鸣声的节拍器时。无法保证您的代码将按时调用,并且无法保证不会遗漏某些代码。你希望它得到保证,你需要编写内核驱动程序,没办法。

  4. 以下是使用PyQt4的完整示例,适用于Python 3.5。它使用QElapsedTimer来衡量按钮按下之间的时间间隔,并使用QTimer来保持时间显示刷新。

    #!/usr/bin/env python
    #https://github.com/KubaO/stackoverflown/tree/master/questions/interval-timer-38036583
    # -*- coding: utf-8 -*-
    import sys
    from PyQt4 import QtCore, QtGui
    
    if __name__ == "__main__":
        running = False
        app = QtGui.QApplication(sys.argv)
        w = QtGui.QWidget()
        layout = QtGui.QVBoxLayout(w)
        label = QtGui.QLabel()
        button = QtGui.QPushButton('Start')
        timer = QtCore.QElapsedTimer()
        updateTimer = QtCore.QTimer()
    
        layout.addWidget(label)
        layout.addWidget(button)
    
        def onTimeout():
            label.setText('Elapsed: {0}ms'.format(timer.elapsed()))
    
        def onClicked():
            global running
            if running:
                onTimeout()
                updateTimer.stop()
                button.setText('Start')
            else:
                timer.start()
                updateTimer.start()
                button.setText('Stop')
            running = not running
    
        updateTimer.setInterval(1000/25) # ~25fps update rate
        updateTimer.timeout.connect(onTimeout)
        button.clicked.connect(onClicked)
    
        w.show()
        sys.exit(app.exec_())
    

答案 1 :(得分:0)

使用标志来控制循环。然后重置连接到停止按钮的插槽中的标志:

        self.startButton.clicked.connect(self.timer)
        self.stopButton.clicked.connect(self.stop)

    def stop(self):
        self._timer_flag = False

    def timer(self):
        timeL = 0
        self._timer_flag = True
        while self._timer_flag:
            self.timeView.display(timeL)
            timeL = timeL + 1
            time.sleep(1)
            app.processEvents()

QTimer更好,因为更新ui没有滞后。但是,您可以通过使用内部循环更频繁地调用processEvents来改进您的示例:

    def timer(self):
        timeL = 0
        self._timer_flag = True
        while self._timer_flag:
            self.timeView.display(timeL)
            timeL = timeL + 1
            for _ in range(10):
                # process events for up to 50 milliseconds
                app.processEvents(QtCore.QEventLoop.AllEvents, 50)
                time.sleep(0.1)

答案 2 :(得分:-2)

听起来你想在QThread上使用QTimer。 这个答案可以为您提供所需的一切。 https://stackoverflow.com/a/18960953/5757280