简体   繁体   中英

Python tkinter buttons are not working during a -while loop- condition

i am doing some measurement with raspberry pi. I made a GUI with python tkinter. measurement is done every seconds. when the measured value is higher than a particular value, i want to set some pin high for 30 seconds (counter). but measurement should continue. and during this time, if there is another high value, again reset the counter to 30 seconds. So i used a while loop. I am displaying measured values in GUI. I am calling the main function (readSensor) every seconds using .after method. During while loop condition, GUI is frozen and value is not updated on screen and buttons are not working. Shall i remove while loop and use .after? but how to use the counter there?

status = False
def start():
    global status
    status = True
def stop():
    global status
    status = False

def readSensor():
    # there is a start and stop button in GUI
    if status:
        measuredValues = []
        pi.write(23,0) # pin 23 is low now
        # code to do measurement is here
        #it works fine
        #result is a list with name measuredValues
        #then checking the conditions below

        if((measuredValues[0] > Limit_1) or (measuredValues[1] > Limit_2) or (measuredValues[2] > Limit_3) or (measuredValues[3] > Limit_4)):
            counter = 0
            print(measuredValues)
            while (counter <=30):
                # this while is the problematic part. if condition is true, i will set the pin 23 high.
                # i would like to set the pin high for 30 seconds
                # no any buttons seems working during this time. why?
                # stop button is also not working.
                pi.write(23,1)
                time.sleep(1.0) #shall i avoid this sleep?
                print(counter)
                measuredValues = []
                #measurement will continue here
                #same code to do measurement as before
                #output is the same list with name measuredValues
                print(measuredValues)
                # if any of the new measuring values is/are higher than limit, want to reset the counter to 30
                # shall I use .after method here? and avoid while loop?
                # how to use it with a condition like maiximum 30s
                if ((measuredValues[0] > Limit_1) or (measuredValues[1] > Limit_2) or (measuredValues[2] > Limit_3) or (measuredValues[3] > Limit_4) ):
                    counter = 0
                else:
                    counter +=1
        else:
            pi.write(23,0)
            print(measuredValues)
    win.after(1000, readSensor) # new measurement every second


win = Tk()
# code for GUI here
win.after(1000, readSensor)
win.mainloop()

You should consider placing your function in a thread. So your start button in your GUI should call the function using:

import threading

start_button = Button(YourFrame, command = lambda:threading.Thread(target = readSensor).start()) #YourFrame is the Frame widget where you placed the start button

That should make the UI responsive while doing the calculations inside your funtion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM