简体   繁体   English

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

[英]using 'stop button' to quit function

So I'm trying to create a timer or sorts, the start button starts the timer, i need to stop the timer with the stop button and then record the time... I can't seem to figure out how to stop the timer function once its started. 所以我正在尝试创建一个计时器或排序,启动按钮启动计时器,我需要用停止按钮停止计时器,然后记录时间......我似乎无法弄清楚如何停止计时器功能一旦开始。 Ive tried if statements, disconnect(), and many others... I realize that there is a timer in qt already but I'm trying to figure it out this way. 我试过if语句,disconnect()和其他许多人......我意识到qt中已经有一个计时器,但我试图用这种方式解决它。 thanks. 谢谢。

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

TL;DR: You're after QElapsedTimer , not QTimer . TL; DR:你是在QElapsedTimer之后,而不是QTimer

The operating system is already measuring the passage of time for you. 操作系统已经为您测量了时间的流逝。 You won't do any better job at it yourself. 你自己也不会做得更好。

"I'm trying to figure it out this way" - it will be less accurate than using QElapsedTimer because you're assuming that exactly as much time has passed as you wished to sleep for. “我试图用这种方式解决这个问题” - 它将不如使用QElapsedTimer准确,因为你假设你想要睡觉的时间已经过去了。 This is almost never true: the actual amount of time that passed is different than the argument to sleep . 这几乎不是真的:实际传递的时间量与sleep的参数不同。 Worse yet, the errors are usually of a systematic kind too, so your time accumulation will have a bias and will get less accurate as time passes. 更糟糕的是,错误通常也是系统性的,因此随着时间的推移,您的时间积累会产生偏差并且会变得不那么准确。 So, don't do it. 所以,不要这样做。 It makes no sense. 这个不成立。 Perhaps you're not telling us exactly what you're trying to do: if you're asking about a particular solution that doesn't work, it helps to say what problem the solution is supposedly to. 也许你并没有告诉我们你正在尝试做什么:如果你问的是一个不起作用的特定解决方案,那么说明该解决方案应该是什么问题会有所帮助。 Why are you trying to figure it out this (wrong) way? 你为什么试图弄清楚这种 (错误的)方式?

There are conceptually three different kinds of timers in Qt: Qt中有三种不同的定时器:

  1. QElapsedTimer is like a stopwatch: it is an interface to the operating system's way of measuring the passage of time. QElapsedTimer就像一个秒表:它是操作系统测量时间流逝的一种界面。 That's the class you should be using to measure how much time has passed between the button clicks. 这是您应该用来衡量按钮点击之间经过了多长时间的课程。

  2. QTime is like a wall clock: you can ask it what time it is through currentTime() , and take difference between two readings of time to obtain elapsed time. QTime就像一个挂钟:你可以通过currentTime()询问它的时间,并在两次读取时间之间取差异以获得经过的时间。 Use this class only if you need to know the absolute time, otherwise QElapsedTimer will offer better resolution for elapsed time measurements. 仅当您需要知道绝对时间时才使用此类,否则QElapsedTimer将为经过时间测量提供更好的分辨率。

  3. QTimer is a source of timeouts: it is a way to periodically call your code. QTimer是超时的来源:它是一种定期调用代码的方法。 This is not meant to be used in measuring time, but merely to let your code run periodically, eg when you wish to refresh screen display, or implement a metronome that beeps periodically. 这并不是用于测量时间,而只是为了让您的代码定期运行,例如,当您希望刷新屏幕显示,或实现定期发出蜂鸣声的节拍器时。 There are no guarantees that your code will be called on time, and no guarantees that some ticks won't be missed. 无法保证您的代码将按时调用,并且无法保证不会遗漏某些代码。 You want it guaranteed, you need to write a kernel driver, no way around that. 你想要它保证,你需要编写一个内核驱动程序,没有办法解决这个问题。

Below is a complete example using PyQt4, for Python 3.5. 下面是使用PyQt4的完整示例,适用于Python 3.5。 It uses QElapsedTimer to measure the passage of time between button presses, and QTimer to keep the time display refreshed. 它使用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_())

Use a flag to control the loop. 使用标志来控制循环。 Then reset the flag in the slot connected to the stop button: 然后重置连接到停止按钮的插槽中的标志:

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

A QTimer is better, because there is no lag in updating the ui. QTimer更好,因为更新ui没有滞后。 But you can improve your example by using an inner loop to call processEvents more frequently: 但是您可以通过使用内部循环更频繁地调用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)

Sounds like you want to use QTimer on a QThread. 听起来你想在QThread上使用QTimer。 This answer should give you everything you need. 这个答案可以为您提供所需的一切。 https://stackoverflow.com/a/18960953/5757280 https://stackoverflow.com/a/18960953/5757280

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM