更新 LCD 数字倒计时
Update LCD Number countdown
我是 Python 的新手,我制作了一个非常简单的倒数计时器。 GUI 是在 Qt Designer 中创建的。有一个用于输入秒数的旋转框、一个开始按钮和一个 LCD 数字计数器。使用以下代码计数器可以正常倒计时:
def start_btn_clicked(self):
x = self.Minute_spinBox.value()
for i in xrange(x,0,-1):
time.sleep(1)
print (i)
为了让我在玩它时能看到发生了什么,我添加了打印指令,以便它在运行时在 Python 控制台中显示倒计时。然后我想我可以很容易地让 LCD 数字显示倒计时,比如:
self.lcdNumber.display(i)("%SS")
但是无论我怎么尝试,我都无法让它显示出来。使用上面的行,我显示了第一个数字,但随后我收到一条错误消息:
self.lcdNumber.display(i)("%SS")
TypeError: 'NoneType' object is not callable
我尝试了太多的变化,以至于我不再知道我从哪里开始,我认为这很简单。我很想知道为什么我不能让它显示倒计时。
display
函数returnsNone
,这样None("%SS")
显然是不行的
self.lcdNumber.display(i)
足以显示倒计时!
让 Qt 在循环 运行 另一个线程的倒计时时绘制小部件。看一个例子。
import time
from threading import Thread
from PyQt4.QtGui import QApplication, QMainWindow, QLCDNumber
class Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.lcdnumber = QLCDNumber(self)
self.resize(400, 400)
t = Thread(target=self._countdown)
t.start()
def _countdown(self):
x = 10
for i in xrange(x,0,-1):
time.sleep(1)
self.lcdnumber.display(i)
if __name__ == "__main__":
app = QApplication([])
window = Window()
window.show()
app.exec_()
for
循环阻塞了 GUI。
连接到按钮 clicked
信号的插槽被 同步处理 。这意味着事件循环必须等待插槽 return 才能处理更多事件(包括更新 GUI 所需的 绘制事件 )。
所以你需要找到一种方法来处理这些事件,而 for
循环是 运行。有多种方法可以做到这一点,例如使用 QTimer or a QThread. But the simplest way of fixing your particular example would be to use QCoreApplication.processEvents.
下面是一个说明如何执行此操作的示例:
import sys, time
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.spinbox = QtGui.QSpinBox(self)
self.spinbox.setValue(5)
self.lcdnumber = QtGui.QLCDNumber(self)
self.button = QtGui.QPushButton('Start', self)
self.button.clicked.connect(self.handleButton)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.spinbox)
layout.addWidget(self.lcdnumber)
layout.addWidget(self.button)
def handleButton(self):
for tick in range(self.spinbox.value(), -1, -1):
self.lcdnumber.display(tick)
self.button.setEnabled(not tick)
# continually process events for one second
start = time.time()
while time.time() - start < 1:
QtGui.qApp.processEvents()
time.sleep(0.02)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 300, 200)
window.show()
sys.exit(app.exec_())
只需在我的原始代码中添加一行代码即可让 lcdNumber 显示计数...
def start_btn_clicked(self):
x = self.Minute_spinBox.value()
for i in xrange(x,0,-1):
time.sleep(1)
app.processEvents() # just this one line allows display of 'i'
self.lcdNumber.display(i)`
并且完美运行
我是 Python 的新手,我制作了一个非常简单的倒数计时器。 GUI 是在 Qt Designer 中创建的。有一个用于输入秒数的旋转框、一个开始按钮和一个 LCD 数字计数器。使用以下代码计数器可以正常倒计时:
def start_btn_clicked(self):
x = self.Minute_spinBox.value()
for i in xrange(x,0,-1):
time.sleep(1)
print (i)
为了让我在玩它时能看到发生了什么,我添加了打印指令,以便它在运行时在 Python 控制台中显示倒计时。然后我想我可以很容易地让 LCD 数字显示倒计时,比如:
self.lcdNumber.display(i)("%SS")
但是无论我怎么尝试,我都无法让它显示出来。使用上面的行,我显示了第一个数字,但随后我收到一条错误消息:
self.lcdNumber.display(i)("%SS")
TypeError: 'NoneType' object is not callable
我尝试了太多的变化,以至于我不再知道我从哪里开始,我认为这很简单。我很想知道为什么我不能让它显示倒计时。
display
函数returnsNone
,这样None("%SS")
显然是不行的
self.lcdNumber.display(i)
足以显示倒计时!
让 Qt 在循环 运行 另一个线程的倒计时时绘制小部件。看一个例子。
import time
from threading import Thread
from PyQt4.QtGui import QApplication, QMainWindow, QLCDNumber
class Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.lcdnumber = QLCDNumber(self)
self.resize(400, 400)
t = Thread(target=self._countdown)
t.start()
def _countdown(self):
x = 10
for i in xrange(x,0,-1):
time.sleep(1)
self.lcdnumber.display(i)
if __name__ == "__main__":
app = QApplication([])
window = Window()
window.show()
app.exec_()
for
循环阻塞了 GUI。
连接到按钮 clicked
信号的插槽被 同步处理 。这意味着事件循环必须等待插槽 return 才能处理更多事件(包括更新 GUI 所需的 绘制事件 )。
所以你需要找到一种方法来处理这些事件,而 for
循环是 运行。有多种方法可以做到这一点,例如使用 QTimer or a QThread. But the simplest way of fixing your particular example would be to use QCoreApplication.processEvents.
下面是一个说明如何执行此操作的示例:
import sys, time
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.spinbox = QtGui.QSpinBox(self)
self.spinbox.setValue(5)
self.lcdnumber = QtGui.QLCDNumber(self)
self.button = QtGui.QPushButton('Start', self)
self.button.clicked.connect(self.handleButton)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.spinbox)
layout.addWidget(self.lcdnumber)
layout.addWidget(self.button)
def handleButton(self):
for tick in range(self.spinbox.value(), -1, -1):
self.lcdnumber.display(tick)
self.button.setEnabled(not tick)
# continually process events for one second
start = time.time()
while time.time() - start < 1:
QtGui.qApp.processEvents()
time.sleep(0.02)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 300, 200)
window.show()
sys.exit(app.exec_())
只需在我的原始代码中添加一行代码即可让 lcdNumber 显示计数...
def start_btn_clicked(self):
x = self.Minute_spinBox.value()
for i in xrange(x,0,-1):
time.sleep(1)
app.processEvents() # just this one line allows display of 'i'
self.lcdNumber.display(i)`
并且完美运行