更新LCD号码倒计时

2024-04-27 05:44:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Python很陌生,我制作了一个非常简单的倒计时。图形用户界面是在Qt设计器中创建的。有一个用于输入秒数的数字显示框、一个启动按钮和一个液晶数字计数器。计数器使用以下代码进行精细倒计时:

     def start_btn_clicked(self):
         x = self.Minute_spinBox.value()
         for i in xrange(x,0,-1):
             time.sleep(1)
             print (i)

为了让我能够看到在使用它时发生了什么,我添加了print指令,以便它在运行时在Python控制台中显示倒计时。然后我想我可以很容易地让液晶数字显示倒计时,比如:

    self.lcdNumber.display(i)("%SS")

但不管我怎么努力,我都无法让它展现出来。上面这一行显示了第一个数字,但随后出现一个错误,说:

    self.lcdNumber.display(i)("%SS")
    TypeError: 'NoneType' object is not callable

我已经尝试了太多的变化,我不再知道我从哪里开始,这里是我认为这将是简单的。我想知道为什么我不能让它显示倒计时。


Tags: 代码selfdisplay计数器数字qt图形用户界面按钮
3条回答

只需在我的原始代码中添加一行代码,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)`

工作完美

display函数返回None,因此显然不允许执行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信号的插槽被同步处理。这意味着事件循环必须等待插槽返回,然后才能处理更多事件(包括更新GUI所需的paint events)。

因此,您需要在运行for循环时找到处理这些事件的方法。有多种方法可以做到这一点,例如使用QTimerQThread。但修复特定示例的最简单方法是使用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_())

相关问题 更多 >