Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 19, 2014 19:54:03

Strelok-den
Зарегистрирован: 2014-03-25
Сообщения: 63
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter и Threading

Всем доброго времени суток, снова возник вопрос но на этот раз глобальный(
Есть код(что ниже), он не работает по понятным причинам, так как вызываю:
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)

Офлайн

#2 Ноя. 19, 2014 22:29:54

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

Tkinter и Threading

Отвечаю на первый: не знаю, так как на маке не работал…
Отвечаю на второй: знаю, не все

Теперь по-вашему вопросу. Вы правы. Есть один блокирующий основной поток событий. Делать многопоточные приложения на Tkinter нужно не так. В этом есть некоторая специфика именно Tkinter. Просто рекомендуется основной поток событий отвязывать от общей структуры и делаеть параллельно другим потокам, т.е. он перестает быть основным. Сумбурно объяснил, но проще объяснить не могу.

Офлайн

#3 Ноя. 19, 2014 23:48:18

Strelok-den
Зарегистрирован: 2014-03-25
Сообщения: 63
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter и Threading

4kpt_II
Отвечаю на первый: не знаю, так как на маке не работал…Отвечаю на второй: знаю, не все Теперь по-вашему вопросу. Вы правы. Есть один блокирующий основной поток событий. Делать многопоточные приложения на Tkinter нужно не так. В этом есть некоторая специфика именно Tkinter. Просто рекомендуется основной поток событий отвязывать от общей структуры и делаеть параллельно другим потокам, т.е. он перестает быть основным. Сумбурно объяснил, но проще объяснить не могу.
Спасибо за ответ, но если честно то мало что понял.. не могли бы привести пример? желательно на моем примере…
Не все.. Какие например?)

Офлайн

#4 Ноя. 20, 2014 00:53:53

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

Tkinter и Threading

Ответ на второй вопрос: PyQt. У него, по-идее, таких проблем быть не должно. Еще wx тоже вроде этого косяка лишен.

По первому. Напишите полноценно задачу, а не этот жутняк… Разбираться в этом нагромождении атрибутов и неверном, в принципе, ООП тупо лень. Ибо не знаешь что править и за что хвататься

Отредактировано 4kpt_II (Ноя. 20, 2014 00:54:23)

Офлайн

#5 Ноя. 20, 2014 01:06:13

Strelok-den
Зарегистрирован: 2014-03-25
Сообщения: 63
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter и Threading

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()

Офлайн

#6 Ноя. 20, 2014 01:09:04

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

Tkinter и Threading

У меня ощущение, что Вы издеваетесь.
Дайте задачу. Что Вы конкретно хотите. Не надо код. Возможно я смогу помочь его реализовать немножко по-другому. Или предложу другой подход к решению.

Офлайн

#7 Ноя. 20, 2014 01:13:16

Strelok-den
Зарегистрирован: 2014-03-25
Сообщения: 63
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter и Threading

4kpt_II
У меня ощущение, что Вы издеваетесь.Дайте задачу. Что Вы конкретно хотите. Не надо код. Возможно я смогу помочь его реализовать немножко по-другому. Или предложу другой подход к решению.

Ни в коем случаи) задача.. задача такова: Запустить окно Toplevel в отдельном потоке, так как пока запускается долгое гуи, у меня выполняются другие потоки.. Так похоже на задачу?) или снова нет(( не умею мысли правильно излагать(

Офлайн

#8 Ноя. 20, 2014 01:24:47

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

Tkinter и Threading

Другие потоки - это не создание графического интерфейса? Просто закачка там данных или еще чего-то. Я правильно понял? А основной поток крутится на гуях и все это отображает, если надо?

Отредактировано 4kpt_II (Ноя. 20, 2014 01:25:14)

Офлайн

#9 Ноя. 20, 2014 01:27:42

Strelok-den
Зарегистрирован: 2014-03-25
Сообщения: 63
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter и Threading

4kpt_II
Другие потоки - это не создание графического интерфейса? Просто закачка там данных или еще чего-то. Я правильно понял?

Да просто потоки, без гуи. При том поток с гуи должен уметь запускать еще потоки с гуи(но не самое главное). И поток с гуи идет в види класса…

Офлайн

#10 Ноя. 20, 2014 01:30:09

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

Tkinter и Threading

Ну с классом это Вы размахнулись Сегодня уже устал как собака. Задачу понял. Завтра выложу код.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version