【问题标题】:Update LCD Number countdown更新液晶数倒计时
【发布时间】:2016-02-23 22:37:13
【问题描述】:

我对 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

我尝试了很多变化,以至于我不再知道从哪里开始,我认为这很简单。我很想知道为什么我不能让它显示倒计时。

【问题讨论】:

    标签: python qt events pyqt qlcdnumber


    【解决方案1】:

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

    而且效果很好

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 但是 'code' self.lcdNumber.display(i)'code' 不显示倒计时,它只在倒计时结束时显示 1 在此之前什么都没有。
      • @Stevo 好吧,您需要将该行放入循环中,就像 print 函数一样。
      • 'code' def start_btn_clicked(self): x = self.Minute_spinBox.value() for i in xrange(x,0,-1): time.sleep(1) self.lcdNumber.display (i) 打印 (i) '代码'
      • 对不起...我无法抓住这个文本框。
      • 这是因为sleep 函数阻塞了主线程,所以Qt 无法绘制小部件。您需要创建另一个线程并从那里运行循环。
      【解决方案3】:

      for 循环阻塞了 GUI。

      连接到按钮的clicked 信号的槽同步处理。这意味着事件循环必须等待槽返回,然后才能处理更多事件(包括更新 GUI 所需的 绘制事件)。

      因此,您需要找到一种在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_())
      

      【讨论】:

      • cdonts 方法绝对是侵入性最小和最简单的方法,一旦用 Deamon 固定,我的原始代码只添加了四行代码。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-04
      相关资源
      最近更新 更多