Форум сайта python.su
Столкнулся с тем, что один и тот же код по разному работает на двух ОС. Точнее в Linux все нормально отрабатывает, а в win xp почему-то, когда выполнение доходит до строчки с выводом уведомления tkinter.messagebox.showinfo(title=“Готово”, message=“Готово.”), уведомление не появляется и окно программы зависает.
Уважаемые гуру, объясните такой момент пожалуйста.
#!/usr/bin/python3 import tkinter import tkinter.messagebox import threading import time class MainWindow(tkinter.Frame): def __init__(self, root): self.root = root self.root.title('test') tkinter.Frame.__init__(self, self.root, height=100, width=1000) self.place(relx=0.5, rely=0.4, anchor="center") self.build_widget() def build_widget(self): self.but_start = tkinter.Button(self, text='Начать') self.but_start.grid(row=0, column=0, pady=30, padx=5) self.but_start.bind("<ButtonRelease-1>", lambda event: threading.Thread(target=self.start, name="task1", args=[5]).start()) def start(self, data): self.but_start['state'] = 'disable' while data > 0: time.sleep(0.5) data -= 1 tkinter.messagebox.showinfo(title="Готово", message="Готово.") self.but_start['state'] = 'active' if __name__ == '__main__': root = tkinter.Tk() root.geometry('100x100') root.resizable(False, False) # Запрещается изменение размеров окна main = MainWindow(root) root.mainloop()
Офлайн
Многопоточность в Tkinter реализуется не так
Офлайн
Офлайн
Спасибо за помощь. Понял свою ошибку и написал решение своей проблемы.
На беседующие, если кто-то наткнётся на эту тему через поиск:
#!/usr/bin/python3 import tkinter import tkinter.messagebox import threading import time class MainWindow(tkinter.Frame): def __init__(self, root): self.root = root self.root.title('test') tkinter.Frame.__init__(self, self.root, height=100, width=100) self.place(relx=0.5, rely=0.4, anchor="center") root.after(1000, self.task) self.build_widget() def build_widget(self): self.but_start = tkinter.Button(self, text='Начать') self.but_start.grid(row=0, column=0, pady=30, padx=5) self.but_start.bind("<ButtonRelease-1>", lambda event: threading.Thread(target=self.start, name="task1").start()) def start(self): """ Запускает процесс получения и обработки данных. """ self.but_start['state'] = 'disable' thread1 = threading.Thread(target=self.parse, name="task1") thread1.start() def parse(self): """ Когда обработка данных закончится в очередь нужно положить True """ time.sleep(5) queue.append(True) def task(self): """ Проверяется завершена задача обработки данных или нет, если завершена, то будет выведено уведомление. """ try: status = queue.pop() except IndexError: status = False if status: self.but_start['state'] = 'active' tkinter.messagebox.showinfo(title="Готово", message="Готово") root.after(1000, self.task) if __name__ == '__main__': queue = [] root = tkinter.Tk() root.geometry('100x100') root.resizable(False, False) # Запрещается изменение размеров окна main = MainWindow(root) root.mainloop()
Отредактировано d54wvzc+i5zirs (Июль 11, 2014 18:28:40)
Офлайн
Написал же. Очередь не нужна!!!!!
Очередной костыль. Еще такое для потомков оставляет
Отредактировано 4kpt_II (Июль 10, 2014 18:25:51)
Офлайн
4kpt_IIНу в этой теме про очереди вы ничего не писали, а вообще согласен, очень была лишней, но с формулировкой “костыль” я не согласен.
Написал же. Очередь не нужна!!!!!Очередной костыль. Еще такое для потомков оставляет
Отредактировано d54wvzc+i5zirs (Июль 11, 2014 12:16:34)
Офлайн
Вот теперь это похоже на правду.
Я писал, что очередь не нужна в топике, из которого Вы взяли большую часть кода. Одна из тех ссылок, которые дал Singularity.
Хорошо. Пусть будет не костыль, а использование модуля без необходимости. Это еще хуже
Ну а теперь по коду, если Вы хотите его кому-то оставлять:
1. Это лишнее:
def __init__(self, root): self.root = root self.root.title('test')
Офлайн
Этот класс служил каркасом в большом проекте, там эти строки были актуальны.
Я просто залез в старый проект и копипнул необходимую часть от туда, по этому тут присутствуют эти строки.
Офлайн
Очень сложно представить, где это может быть актуально…
Приведите пример класса, где нужно явно создавать атрибут и привязывать его к переданному root. Это даже интересно.
Никогда в жизни такого не видел и вряд-ли увижу. Точнее надеюсь, что не увижу.
Отредактировано 4kpt_II (Июль 11, 2014 18:51:36)
Офлайн