Форум сайта python.su
15
Вот сценарий:
import threading import time from tkinter import Tk from tkinter import Label TIMEOUT = 10 # Время в секундах, по истечении которго будет посылаться запрос на получение данных. # Функция, которая будет обновлять данные. def waiter(func): while True: time.sleep(TIMEOUT) func() def main(): root_widg = Tk() root_widg.title('Уведомление по неотвеченным вопросам') root_widg.geometry("{}x{}+0+0".format(root_widg.winfo_screenwidth(), root_widg.winfo_screenheight())) root_widg.attributes('-fullscreen', 1) label = Label(root_widg, justify='left', wraplength=root_widg.winfo_screenwidth() - 20) label.pack(expand='yes', fill='both') def output(): # тут делаю запрос на сервер # получаю ответ # паршу ответ # и в зависимости от пришедших параметров конфигурирую label # например label.config(text="Успех", bg='#78207E', fg='#4FEDEE', font=('times', 20, 'bold')) thread = threading.Thread(target=waiter, args=(output,)) thread.start() def escape(event): root_widg.quit() def leave(event): root_widg.attributes('-fullscreen', 0) def enter(event): root_widg.attributes('-fullscreen', 1) root_widg.bind('<Escape>', escape) root_widg.bind('<Alt-F4>', escape) root_widg.bind('<FocusIn>', enter) root_widg.bind('<FocusOut>', leave) output() root_widg.mainloop() if __name__ == '__main__': main()
Отредактировано buddha (Июль 5, 2013 17:23:11)
Офлайн
63
Не уверен, что threading будет дружить с tkinter. У tkinter существуют свои механизмы запуска дополнительного цикла обработки событий.
P.S. Никогда не испытывал связку threading и tkinter. Может кто пробовал, тот напишет более внятный ответ или механизм борьбы с Вашей проблемой.
Офлайн
15
Какой механизм? Через него можно через каждые 10 секунд запускать функцию output(), при этом чтобы отлавливание клавиш не отвалилось?
Офлайн
63
Такие задачи себе не ставил. По-идее можно.
Сейчас попробую и отпишусь.
Отредактировано 4kpt (Июль 5, 2013 17:11:23)
Офлайн
63
Получилось. Ну и задачка…
P.S. Вопрос еще актуален?
Отредактировано 4kpt (Июль 5, 2013 19:05:58)
Офлайн
15
да, актуально.
4kptПришлось поколдлвать? какие сложности? Я так просто тупо не знаю, почему так себя ведёт програмка.
Ну и задачка…
Офлайн
63
Будете смеяться. Все прозаично и просто. Никаких костылей :)
Ловите…
# -*- coding: utf-8 -*- import Tkinter import time tm = time.time() def call_passive(event): print u"Выполнен шаг процесса." # Будет запускаться 10 секунд через каждую секунду if time.time() - tm < 10: root.after(1000, call_passive, event) def call_active(event): print u"Пассивное нажатие в процессе." root = Tkinter.Tk() root.geometry("400x400+100+100") bt_free = Tkinter.Button(root, width=20, text="Свободно нажимаем") bt_free.place(relx=0.5, rely=0.33, anchor="center") bt_free.bind("<ButtonRelease-1>", call_active) bt_proc = Tkinter.Button(root, width=20, text=u"Запускаем процесс") bt_proc.place(relx=0.5, rely=0.66, anchor="center") bt_proc.bind("<ButtonRelease-1>", call_passive) root.mainloop()
Отредактировано 4kpt (Июль 6, 2013 00:13:35)
Офлайн
15
Ага вижу, рекусия в методе after(). В гугле видел её, но не пробовал. Попробую поменять реализацию сценария. Отпишусь потом…
Офлайн
63
По гуглю не искал, не знаю, но метод .after() в tkinter запускает параллельный поток событий. О нем я писал выше. Но при его применении с циклом происходило выполнение всех событий одновременно. Если же использовался модуль time, то имело место зависание основного потока. Оставалось только одно - рекурсия, чтобы не ваять цикл, который этот поток событий будет стопарить. В этом случае .after вызывает функцию, котора вызывает в отдельном потоке .after и так циклично. Получается все “по-феншую” :)
Отредактировано 4kpt (Июль 6, 2013 10:50:02)
Офлайн
15
Ну, а что будет когда рекурсия достигнет своего предела?
>>> sys.getrecursionlimit() 1000
Отредактировано buddha (Июль 8, 2013 08:51:16)
Офлайн