4

I have the following code which will start after clicking the 'Start' button in 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)"

The above program is for ADC reading and it will start after clicking the pushbutton called 'Start' as : self.pushButton.clicked.connect( self.Start)

And I have another pushButton_2 called 'Stop' and by clicking this the above process should stop.Please suggest, so I can able to do that.

lkkkk
  • 1,589
  • 4
  • 20
  • 27

2 Answers2

5

There is no need to do anything other than what I suggested in your other question on this topic: just use processEvents. As long as you can call it frequently enough (but not too frequently), it should do exactly what you want. Using your second example, the following works fine for me:

  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()
Community
  • 1
  • 1
ekhumoro
  • 98,079
  • 17
  • 183
  • 279
  • Just a note that every post I read about processEvents cautions that it should be a last resort after QThread and QTimer based approaches. Unfortunately I have not been able to find any clear reasons why, possibly due to the fact that it only processes certain types of events, and only from the thread that calls the function, so maybe it is one of those functions that is easy to use but if it doesn't just work, it can be hard to figure out why. In the case of OP I would rather suggest QThread. – Oliver Apr 16 '14 at 01:44
  • 1
    @Schollii. Yes, I too have encountered this inexplicable "sniffiness" regarding `processEvents`: as if `QThread` and `QTimer` etc don't also have their limitations (especially where python is concerned). There are many tools in this particular box, and no single one of them will work in all possible situations. So it seems silly to me to say that one of them should be a "last resort": rather, one should learn how to use all the tools in the box, and then pick the best one for the job in hand. – ekhumoro Apr 16 '14 at 02:52
  • Agreed, and a major challenge is learning the criteria for "the best one for the job in hand"; I have yet to see a clear comparison of the three approaches with considerations for each that could be used to determine which one to pick in given situation. – Oliver Apr 16 '14 at 02:58
  • @Schollii. I imagine such a comparison (if done thoroughly) could run to quite a few pages... – ekhumoro Apr 16 '14 at 03:09
-1
  1. This question is useful: tkinter loop and serial write It could be copied over with two changes: master.update becomes QtGui.qApp.processEvents and master.after becomes QTimer.singleShot.

  2. Here is a sketch of how to do what you ask for with 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
                # ...
    

    Since I do not know what your code look like, here is a working example using PyQT4 and 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 uses QTimer.singleShot(time, function) to make the loop continue.

    You can also stop the loop with stopLoop() of guiLoop.

Community
  • 1
  • 1
User
  • 12,769
  • 1
  • 32
  • 55
  • Please have a look at question again I have added one simple example, and I tried doing as you advised me , but there is something going wrong. Sorry as I am new to all these.. – lkkkk Apr 14 '14 at 14:17
  • sorry.. please suggest I have edited my question that is in last example for the StartLoop(): as it again not working I thing because of having loop in loop. – lkkkk Apr 15 '14 at 06:22