Запуск диалогового окна в отдельном потоке и управление им по таймеру на python
Программа работает на одноплатнике Raspberry, на python. Мониторит состояние пина. Если на пине появился сигнал, открывается диалоговое окно и ждем реакции пользователя. Параллельно нужно продолжать мониторить тот же пин. Если в течение 3 секунд на нем вновь появился сигнал, то все ок, продолжаем ждать реакции пользователя (он может нажимать кнопки в диалоге, что вызывает другие окна и т.п.). Если же в течение 3 сек сигнал на пин не поступил, диалог (и все прочие открытые окна) надо зарыть. Далее ждем опять сигнал, показываем диалог, мониторим пин и т.п. Т.е. диалог работает при условии, что не реже раз в 3 сек на пин поступает сигнал.
Как я понимаю, тут нужен таймер на 3 сек, который запускается в отдельном потоке. Таймер нужно обнулять, если пин изменил состояние и снова засекать 3 сек. Если 3 сек прошли, вызывать колбэк, который будет делать Gtk.main_quit(). Как-то так. Но это по сути моя вторая программа на питоне )). Т.е. я с потоками не очень (мягко говоря).
import gi
import RPi.GPIO as GPIO
from threading import Thread, Timer
def gui_close():
print('Убираем GUI')
Gtk.main_quit()
def gui_open()
print('Открываем GUI')
dialog = GtkDialog()
dialog.show_all()
Gtk.main()
tmr = Timer(3, gui_close)
def signal_detected():
#здесь нужно обнулить (запустить заново) таймер
#и запустить поток с GUI,
#если он еще не запущен
GPIO.setmode(GPIO.BCM)
SIGNAL_PIN = 12
GPIO.setup(SIGNAL_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(SIGNAL_PIN, GPIO.FALLING, callback=signal_detected)
Пожалуйста, знающие люди, помогите разобраться с потоками ).
Ответы (1 шт):
GTK не работает в потоках. Маин обычно запускается на все время работы программы и не закрывается до выхода. Показ окна осуществляется через show, скрывается через hide. Нет особой нужды создавать новые окна.
Ваш код переносится в поток. Взаимодействие с GUI же строится только через вызов gobject.idle_add
Таймер встраивайте в окно и запускайте вместе с show. Хотя лучше его убрать и использовать GObject.timeout_add