Форум сайта python.su
Вот сценарий:
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)
Офлайн
Не уверен, что threading будет дружить с tkinter. У tkinter существуют свои механизмы запуска дополнительного цикла обработки событий.
P.S. Никогда не испытывал связку threading и tkinter. Может кто пробовал, тот напишет более внятный ответ или механизм борьбы с Вашей проблемой.
Офлайн
Какой механизм? Через него можно через каждые 10 секунд запускать функцию output(), при этом чтобы отлавливание клавиш не отвалилось?
Офлайн
Такие задачи себе не ставил. По-идее можно.
Сейчас попробую и отпишусь.
Отредактировано 4kpt (Июль 5, 2013 17:11:23)
Офлайн
Получилось. Ну и задачка…
P.S. Вопрос еще актуален?
Отредактировано 4kpt (Июль 5, 2013 19:05:58)
Офлайн
да, актуально.
4kptПришлось поколдлвать? какие сложности? Я так просто тупо не знаю, почему так себя ведёт програмка.
Ну и задачка…
Офлайн
Будете смеяться. Все прозаично и просто. Никаких костылей :)
Ловите…
# -*- 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)
Офлайн
Ага вижу, рекусия в методе after(). В гугле видел её, но не пробовал. Попробую поменять реализацию сценария. Отпишусь потом…
Офлайн
По гуглю не искал, не знаю, но метод .after() в tkinter запускает параллельный поток событий. О нем я писал выше. Но при его применении с циклом происходило выполнение всех событий одновременно. Если же использовался модуль time, то имело место зависание основного потока. Оставалось только одно - рекурсия, чтобы не ваять цикл, который этот поток событий будет стопарить. В этом случае .after вызывает функцию, котора вызывает в отдельном потоке .after и так циклично. Получается все “по-феншую” :)
Отредактировано 4kpt (Июль 6, 2013 10:50:02)
Офлайн
Ну, а что будет когда рекурсия достигнет своего предела?
>>> sys.getrecursionlimit() 1000
Отредактировано buddha (Июль 8, 2013 08:51:16)
Офлайн