Форум сайта python.su
Всем доброго времени суток, снова возник вопрос но на этот раз глобальный(
Есть код(что ниже), он не работает по понятным причинам, так как вызываю:
Tkinter из другого потока, а можно только из главного (root = Tk())
В мак ос это работает и я не задумывался над этим, но после запуска этого же кода на виндовс получил массу проблем и эту в том числе.
Как можно переделать код, чтобы не было этой проблемы, без ущерба производительности?
Читал про похожую проблему уже на форуме, но там человек нашол решение ввиди Queue(очереди), но есть ли другие варианты? и мини вопрос, даже два: почему в мак ос проблем не получил? и все ли гуи так относятся к потокам?
class dowloads(): def toplevel(self): self.down = Toplevel() self.down.title(u"Загрузка") frames = self.down center_window(frames, 400, 170) def prog_start(self): self.progressVar = IntVar(self.down) self.progress = Progressbar(self.down, value = 100, length=345, variable = self.progressVar) self.progress.grid(row=2, column=3, pady = 4, sticky = 'w', padx=7, columnspan=1) #self.progress.start(5) #self.progress.step(20) def label1(self): self.l1 = Label(self.down) self.l1["fg"] = "red" self.l1["font"] = "Helvetica 12" self.l1.grid(row=2, column=4, sticky = 'ne', columnspan=1) l0 = Label(self.down) l0.grid(row=0, column=0, sticky = 'news', padx = 4, pady = 10, columnspan=10) self.l2 = Label(self.down) self.l2.grid(row=1, column=0, sticky = 'nw', padx = 4, pady = 0, columnspan=10) self.l3 = Label(self.down) self.l3.grid(row=3, column=0, sticky = 'sw', padx = 4, columnspan=10) self.l2["font"] = "Helvetica" self.l3["font"] = "Helvetica 12 italic" self.l2["text"] = u'Подготовка... ' self.l1["text"] = u' 0%' self.l2.config(width=40, justify='left', anchor='nw') self.l3.config(width=40, justify='left', anchor='sw') self.l1.config(width=5, justify='right', anchor='ne') self.b1 = Button(self.down) self.b1["text"] = u'Остановить загрузку' self.b1["command"] = restart_program self.b1.grid(row=4, column=0, pady=10, columnspan=20) self.b1.config(width=20) def state_norm(self, event): self.k1['state'] = 'normal' self.k2['state'] = 'normal' self.k3['state'] = 'normal' def __init__(self, OSS, k1, k2, k3): root.attributes("-topmost", False) self.k1 = k1 self.k2 = k2 self.k3 = k3 self.OSS = OSS self.toplevel() self.prog_start() self.label1() threading.Thread(target=dowloads, args=(self.OSS, self.hi_there, self.QUIT, self.settings)).start() #вызываю классв новом потоке и он зависает так как: #Нельзя вызывать методы Tkinter из других потоков, кроме как из главного (там где root = Tk())
Отредактировано Strelok-den (Ноя. 19, 2014 19:54:58)
Офлайн
Отвечаю на первый: не знаю, так как на маке не работал…
Отвечаю на второй: знаю, не все
Теперь по-вашему вопросу. Вы правы. Есть один блокирующий основной поток событий. Делать многопоточные приложения на Tkinter нужно не так. В этом есть некоторая специфика именно Tkinter. Просто рекомендуется основной поток событий отвязывать от общей структуры и делаеть параллельно другим потокам, т.е. он перестает быть основным. Сумбурно объяснил, но проще объяснить не могу.
Офлайн
4kpt_IIСпасибо за ответ, но если честно то мало что понял..
Отвечаю на первый: не знаю, так как на маке не работал…Отвечаю на второй: знаю, не все Теперь по-вашему вопросу. Вы правы. Есть один блокирующий основной поток событий. Делать многопоточные приложения на Tkinter нужно не так. В этом есть некоторая специфика именно Tkinter. Просто рекомендуется основной поток событий отвязывать от общей структуры и делаеть параллельно другим потокам, т.е. он перестает быть основным. Сумбурно объяснил, но проще объяснить не могу.
Офлайн
Ответ на второй вопрос: PyQt. У него, по-идее, таких проблем быть не должно. Еще wx тоже вроде этого косяка лишен.
По первому. Напишите полноценно задачу, а не этот жутняк… Разбираться в этом нагромождении атрибутов и неверном, в принципе, ООП тупо лень. Ибо не знаешь что править и за что хвататься
Отредактировано 4kpt_II (Ноя. 20, 2014 00:54:23)
Офлайн
4kpt_II
Ответ на второй вопрос: PyQt. У него, по-идее, таких проблем быть не должно. Еще wx тоже вроде этого косяка лишен.По первому. Напишите полноценно задачу, а не этот жутняк… Разбираться в этом нагромождении атрибутов и неверном, в принципе, ООП тупо лень. Ибо не знаешь что править и за что хвататься
class dowloads(): def toplevel(self): self.down = Toplevel() self.down.title(u"Загрузка") def label1(self): self.l1 = Label(self.down) self.l1["fg"] = "red" self.l1["font"] = "Helvetica 12" self.l1.grid(row=2, column=4, sticky = 'ne', columnspan=1) def __init__(self): self.toplevel() self.label1() threading.Thread(target=dowloads, args=()).start()
class test(threading.Thread): pass test().start()
Офлайн
У меня ощущение, что Вы издеваетесь.
Дайте задачу. Что Вы конкретно хотите. Не надо код. Возможно я смогу помочь его реализовать немножко по-другому. Или предложу другой подход к решению.
Офлайн
4kpt_II
У меня ощущение, что Вы издеваетесь.Дайте задачу. Что Вы конкретно хотите. Не надо код. Возможно я смогу помочь его реализовать немножко по-другому. Или предложу другой подход к решению.
Офлайн
Другие потоки - это не создание графического интерфейса? Просто закачка там данных или еще чего-то. Я правильно понял? А основной поток крутится на гуях и все это отображает, если надо?
Отредактировано 4kpt_II (Ноя. 20, 2014 01:25:14)
Офлайн
4kpt_II
Другие потоки - это не создание графического интерфейса? Просто закачка там данных или еще чего-то. Я правильно понял?
Офлайн
Ну с классом это Вы размахнулись Сегодня уже устал как собака. Задачу понял. Завтра выложу код.
Офлайн