Кнопки Python tkinter не работают во время цикла - PullRequest
0 голосов
/ 03 июля 2019

Я делаю некоторые измерения с Raspberry Pi.Я сделал графический интерфейс с Python Tkinter.измерение производится каждые секунды.Когда измеренное значение выше, чем конкретное значение, я хочу установить высокий вывод на 30 секунд (счетчик).но измерение должно продолжаться.и в течение этого времени, если есть другое высокое значение, снова сбросьте счетчик на 30 секунд.Так что я использовал цикл while.Я отображаю измеренные значения в графическом интерфейсе.Я вызываю основную функцию (readSensor) каждую секунду, используя метод .after.В то время как в то время как цикл цикла, 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 голосов
/ 03 июля 2019

Вы должны рассмотреть возможность размещения своей функции в потоке.Таким образом, ваша кнопка запуска в вашем графическом интерфейсе должна вызывать функцию, используя:

import threading

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

Это должно сделать пользовательский интерфейс отзывчивым при выполнении вычислений внутри вашей функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...