Это вторая версия программы, с которой я борюсь. Я отправил более ранний вопрос с первой версией программы, но мне не повезло.Как прерывать цикл GPIO RPi в любое время с помощью кнопки TKinter
Вот моя «Большая картинная идея» на случай, если она поможет вам найти место, где я ухожу. У меня много растений для воды, и я хочу создать графический интерфейс с TKinter, который появится на сенсорном экране на малиновой пи. Pi управляет реле 110 В, которое подключается к водяному насосу. Его просто базовая петля «вкл/выкл» для z # растений.
Пользователь имеет три ползунка для регулировки, X, Y и Z. X - как долго должен быть включен водяной насос, Y - как долго должен быть выключен водяной насос (так что у вас есть время, чтобы физически переместить шланг на следующую установку), а Z - общее количество заводов, которые вы должны воды. Раньше я просто позволял циклу работать навсегда, потому что всегда мог CTRL-C завершить программу, но теперь я пытаюсь сделать все это на сенсорном экране без клавиатуры - более удобный, чем преподавание того, кто не знать, что означает Linux, как использовать терминал. Он также должен запускаться как программа, к которой люди привыкли видеть, поэтому кнопки сенсорного экрана GUI (например, смартфоны и планшеты).
Код работает хорошо по большей части, он останавливается и запускается без сбоев. Я понял, кнопка запуска, и есть кнопка сброса, чтобы очистить значения ползунка, если вы хотите начать значения над нулями. Но проблема BIG, которая, кажется, затрагивает многих людей здесь, - это кнопка «ВЫХОД».
Мне нужно, чтобы пользователь мог нажать кнопку TKinter EXIT в любое время во время цикла и знать программу, когда кнопка нажата, и выполнять ее немедленно, в основном прерывая цикл. Я много пробовал, ничего не работает. Checkbuttons будет ждать только завершения цикла, а затем обновить значение переключения. В этот момент уже слишком поздно; Мне нужен пользовательский контроль во время всего цикла полива.
Я также не хочу, чтобы программа выходила, когда нажата кнопка EXIT, а я хочу, чтобы цикл GPIO остановился на значении «ВЫКЛ» и в основном сбросил программу в начальное состояние.
Я знаю, что time.sleep()
очень грубо, но я не нашел другого способа сделать это. Я видел, как люди говорили о «потоке», я понятия не имею, что это значит, и похоже, что я никогда не буду. Я также видел, как люди говорят о функции «после()» TKinters, опять же, мне нужны очень четкие примеры ответов. Просто говоря «Использовать потоки» не дает никакой помощи - я ноб!
from tkinter import *
import RPi.GPIO as GPIO
import time
master = Tk()
def onoffcycle():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(14, GPIO.OUT)
GPIO.setup(14, GPIO.LOW)
y=off.get()
y=float(y)
x=on.get()
x=float(x)
GPIO.output(14, True)
print("On")+str(x)
time.sleep(x)
GPIO.output(14, False)
print("Off")+str(y)
time.sleep(y)
def start():
print("Prepare to water in 10 seconds...")
time.sleep(10)
z=cycle.get()
z=float(z)
while z > 0:
onoffcycle()
z=z-1
print("Cycles remaining:")+str(z)
###tog()
###if t==1:
###reset()
else:
reset()
### this program runs onoffcycle() for z number of cycles as set by the slider.
### It should check for an exit toggle, then run the program for one cycle,
### then check for exit, then another round. countdown from cycle.get variable
def reset():
GPIO.cleanup()
on.set(0)
off.set(0)
cycle.set(0)
t=IntVar()
###def tog():
### HELP! This is where I need the program to be looking for the EXIT button being pressed
### in order to stop the program. Everything I have tried so far waits until the z value drops
### to zero, basically until the program stops on its own. I need a button that interrupts
### everything.
on = Scale(master, label="Set # Seconds Water ON:", from_=0, to=180, orient=HORIZONTAL, length=400, width=35,
troughcolor="red", bg="SteelBlue1", fg="black", bd=6, sliderlength=90, sliderrelief=RIDGE,
font = '-weight bold')
on.grid(column=1, row=1, columnspan=3)
off = Scale(master, label="Set # Seconds Water OFF:", from_=0, to=30, orient=HORIZONTAL, length=400, width=35,
troughcolor="yellow", bg="SteelBlue1", fg="black", bd=6, sliderlength=90, sliderrelief=RIDGE,
font = '-weight bold')
off.grid(column=1, row=2, columnspan=3)
cycle = Scale(master, label="Set # of Plants to Water:", from_=0, to=200, orient=HORIZONTAL, length=400, width=35,
troughcolor="green", bg="SteelBlue1", fg="black", bd=6, sliderlength=90, sliderrelief=RIDGE,
font = '-weight bold')
cycle.grid(column=1, row=3, columnspan=3)
go = Button(master, text="START", command=start, bg="SteelBlue3", width=10, height=2, font='-weight bold')
go.grid(column=1, row=4)
adios = Checkbutton(master, text="EXIT", variable=t, indicatoron=0, bd=6, bg="SteelBlue3", width=11, height=2, font='-weight bold')
adios.grid(column=3, row=4)
###adios should have a command to run an exit program - with toggle values? or something else?
resetbutton = Button(master, text="RESET", command=reset, bg="SteelBlue3", width=10, height=2, font='-weight bold')
resetbutton.grid(column=2, row=4)
mainloop()
вы должны использовать 'root.after (миллисекунды, имя_функции)' вместо 'sleep()' и 'while'. '10s = 10000ms', то есть,' root.after (10000, start) 'в конце' start() 'должен снова запустить эту функцию через 10 секунд, и вам не нужно' sleep() ', и вы не нужно 'while', но' if', чтобы остановить 'after'. – furas
'print (« Вкл. ») + Str (x)' не имеет смысла, потому что 'print' возвращает' None', поэтому вы делаете 'None + str (x)'. Возможно, вам нужно «print (« Вкл. », X)» или, по крайней мере, «print (« Вкл. »+ Str (x))» или «print (« On {} ». Format (x))', но первая версия Простейшие. – furas
furas - спасибо за столько информации! Части print() печатают выбранные пользователем значения в командной строке; Я полагаю, что это действительно не предназначено для просмотра пользователем, так как я хочу, чтобы окно TKinter было полноэкранным. Я использую его во время отладки, и в конце концов это может быть полезно. – Stephen