所以我正在尝试创建一个计时器或排序,启动按钮启动计时器,我需要用停止按钮停止计时器然后记录时间...我似乎无法弄清楚如何一旦启动,就停止计时器功能。我试过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_()
答案 0 :(得分:2)
TL; DR:你在QElapsedTimer
之后,而不是QTimer
。
操作系统已经在测量你的时间。你自己也不会做得更好。
“我试图通过这种方式弄明白” - 它不如使用QElapsedTimer
那么准确,因为你假设你想要睡觉的时间已经过去了。这几乎不是真的:实际传递的时间量与sleep
的参数不同。更糟糕的是,错误通常也是系统性的,因此随着时间的推移,您的时间积累会产生偏差并且会变得不那么准确。所以,不要这样做。这没有道理。也许你并没有告诉我们你正在尝试做什么:如果你问的是一个不起作用的特定解决方案,那么说明该解决方案应该是什么问题会有所帮助。 为什么你想弄清楚这个(错误的)方式?
Qt中有三种不同的计时器:
QElapsedTimer
就像秒表:它是操作系统测量时间流逝的一种界面。这是您应该用来衡量按钮点击之间经过了多长时间的课程。
QTime
就像一个挂钟:您可以通过currentTime()
询问它的时间,并在两次读取时间之间取差异以获得经过的时间。仅在您需要知道绝对时间时才使用此课程,否则QElapsedTimer
将为经过时间测量提供更好的分辨率。
QTimer
是超时的来源:它是一种定期调用代码的方法。这并不意味着用于测量时间,而只是让您的代码定期运行,例如当您希望刷新屏幕显示,或实现定期发出蜂鸣声的节拍器时。无法保证您的代码将按时调用,并且无法保证不会遗漏某些代码。你希望它得到保证,你需要编写内核驱动程序,没办法。
以下是使用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