كيفية إنهاء البرنامج أثناء الحلقة باستخدام زر الضغط في PyQt

StackOverflow https://stackoverflow.com//questions/23057031

  •  23-12-2019
  •  | 
  •  

سؤال

لدي الكود التالي والذي سيبدأ بعد النقر فوق الزر "ابدأ" في 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 يسمى "إيقاف" وبالنقر فوق هذا، يجب أن تتوقف العملية المذكورة أعلاه. يرجى الاقتراح، حتى أتمكن من القيام بذلك.

هل كانت مفيدة؟

المحلول

  1. هذا السؤال مفيد: حلقة tkinter والكتابة التسلسلية يمكن نسخه مع تغييرين: master.update يصبح QtGui.qApp.processEvents و master.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) لجعل الحلقة تستمر.

    يمكنك أيضًا إيقاف الحلقة باستخدام stopLoop() من guiLoop.

نصائح أخرى

ليست هناك حاجة لفعل أي شيء آخر غير ما اقترحته وفي سؤالك الآخر حول هذا الموضوع:مجرد استخدام 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()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top