【问题标题】:How to quit the program in while loop using push-button in PyQt如何使用 PyQt 中的按钮在 while 循环中退出程序
【发布时间】:2014-04-14 09:52:33
【问题描述】:

我有以下代码将在 PyQt 中单击“开始”按钮后开始:

def Start(self):
  import time
  import os
  import RPi.GPIO as GPIO
  import datetime

  GPIO.setmode(GPIO.BCM)
  DEBUG = 1

  os.system('clear')

  # SPI port on GPIO
  SPICLK = 18
  SPIMISO = 23
  SPICS = 25

  # set up the SPI interface pins
  GPIO.setup(SPIMISO, GPIO.IN)
  GPIO.setup(SPICLK, GPIO.OUT)
  GPIO.setup(SPICS, GPIO.OUT)

  GPIO.output(SPICS, True)
  GPIO.output(SPICS, False) # bring CS low
  while True:
        adcout = 0             
        read_adc = 0
        #s=time.clock()
        for i in range(25):
            GPIO.output(SPICLK, True)
            GPIO.output(SPICLK, False)
            adcout <<= 1
            if (GPIO.input(SPIMISO)==1):
                adcout |= 0x1
        time.sleep(0.085)   
        if (GPIO.input(SPIMISO)==0):
            read_adc = adcout
            millivolts = read_adc * ( 2500.0 /(pow(2,22)))
            read_adc = "%d" % read_adc
            millivolts = "%d" % millivolts

        if DEBUG:
            print millivolts, "mV (ADC)"

上述程序用于 ADC 读取,单击“开始”按钮后将启动:self.pushButton.clicked.connect( self.Start)

我还有另一个 pushButton_2 称为“停止”,单击此按钮应该停止上述过程。请提出建议,以便我能够这样做。

【问题讨论】:

    标签: python pyqt adc


    【解决方案1】:

    在您关于此主题的其他问题中,除了what I suggested 之外无需执行任何操作:只需使用processEvents。只要您可以足够频繁地调用它(但不是频繁),它就应该完全按照您的意愿行事。使用您的第二个示例,以下对我来说很好:

      def Start(self):
        if not self.started:
            self.started = True
            self.StartLoop()
    
      def Stop(self):
        if self.started:
            self.started = False
    
      def StartLoop(self):
        DEBUG = 1
        while self.started:
            print "LED on "
            time.sleep(0.05)
            print "LED off "
            time.sleep(0.085)
            QtGui.qApp.processEvents()
    

    【讨论】:

    • 请注意,我读到的每篇关于 processEvents 的文章都警告说,它应该是基于 QThread 和 QTimer 的方法之后的最后手段。不幸的是,我无法找到任何明确的原因,可能是因为它只处理某些类型的事件,并且只处理调用函数的线程,所以也许它是那些易于使用的函数之一但如果它不能正常工作,就很难找出原因。在 OP 的情况下,我宁愿建议 QThread。
    • @Schollii。是的,我也遇到过这种关于processEvents 的莫名其妙的“嗅觉”:好像QThreadQTimer 等也没有它们的局限性(尤其是在涉及python 的情况下)。在这个特定的盒子里有很多工具,没有一种工具可以在所有可能的情况下工作。所以在我看来,说其中一个应该是“最后的手段”似乎很愚蠢:相反,一个人应该学习如何使用盒子里的所有工具,然后选择最适合手头工作的工具。
    • 同意,一个主要的挑战是学习“最适合手头工作的人”的标准;我还没有看到这三种方法的清晰比较,每种方法的考虑可用于确定在给定情况下选择哪一种。
    • @Schollii。我想这样的比较(如果彻底完成的话)可能会跑到好几页......
    【解决方案2】:
    1. 这个问题很有用:tkinter loop and serial write 可以通过两个更改来复制它:master.update 变为 QtGui.qApp.processEventsmaster.after 变为 QTimer.singleShot

    2. 以下是如何使用guiLoop 完成您所要求的操作的草图:

      from guiLoop import guiLoop, stopLoop
      # ... means fill in your code
      class ...: 
          started = False
      
          def Start(self):
              if not self.started:
                  # you can also use threads here, see the first link
                  self.started = self.StartLoop()
      
          def Stop(self):
              if self.started:
                  stopLoop(self.started)
                  self.started = False
      
          @guiLoop
          def StartLoop(self):
              # This is your Start function
              # ...
              while True:
                  # ...
                  yield 0.085 # time.sleep(0.085) equivalent
                  # ...
      

      由于我不知道你的代码是什么样的,这里是一个使用 PyQT4 和 guiLoop 的工作示例:

      from PyQt4 import QtGui
      import sys
      
      from guiLoop import guiLoop # https://gist.github.com/niccokunzmann/8673951
      
      @guiLoop
      def led_blink(argument):
          while 1:
              print("LED on " + argument)
              yield 0.5 # time to wait
              print("LED off " + argument)
              yield 0.5
      
      app = QtGui.QApplication(sys.argv)
      
      w = QtGui.QWidget()
      w.resize(250, 150)
      w.move(300, 300)
      w.setWindowTitle('Simple')
      w.show()
      
      led_blink(w, 'shiny!')
      
      sys.exit(app.exec_())
      

      guiLoop 使用QTimer.singleShot(time, function) 使循环继续。

      您也可以使用 guiLoop 的stopLoop() 停止循环。

    【讨论】:

    • 请再看一遍问题我已经添加了一个简单的例子,我尝试按照你的建议做,但是出了点问题。对不起,我对所有这些都是新手..
    • 对不起.. 请建议我编辑了我在 StartLoop() 的最后一个示例中的问题:因为它再次无法正常工作,因为循环中有循环。
    猜你喜欢
    • 2022-10-08
    • 1970-01-01
    • 2017-06-14
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    相关资源
    最近更新 更多