在-while循环条件下,Python tkinter按钮不起作用

时间:2019-07-03 08:48:14

标签: python user-interface tkinter

我正在用树莓派做一些测量。我用python tkinter制作了一个GUI。每秒钟进行一次测量。当测量值高于特定值时,我想将某个引脚设置为高电平30秒(计数器)。但测量应继续进行。在此期间,如果还有另一个较高的值,请再次将计数器重置为30秒。所以我用了while循环。我正在GUI中显示测量值。我使用.after方法每秒钟调用一次主要函数(readSensor)。在while循环期间,GUI被冻结,并且屏幕上的值未更新,并且按钮不起作用。我应该删除while循环并使用.after吗?但是在那里如何使用计数器?

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

1 个答案:

答案 0 :(得分:0)

您应该考虑将函数放在线程中。因此,GUI中的开始按钮应使用以下命令调用函数:

import threading

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

这应该使UI在执行功能内的计算时响应。