Уведомления

Группа в Telegram: @pythonsu

#1 Март 2, 2010 17:35:54

somaniac
От:
Зарегистрирован: 2009-01-30
Сообщения: 22
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter, toplevel и потоки ЧЯДНТ?

Доброго времени суток!
Хочу сделать в приложении всплывающее окно с полем ввода. Приведенный ниже код работает, но есть одна неприятная особенность - при открытии toplevel-окна в совершенно произвольные моменты происходит подвисание программы. Открывается пустое окно у которого в заголовке написан числовой идентификатор и все вешается наглухо. Загрузка процессора не меняется. Использую ActiveState Python 2.5. Глюк проверялся на нескольких компах и везде проявляется одинаково. Что я делаю не так?

class EntryForm():
'''Форма ввода'''
def __init__(self, root = None, pict=''):
self.tl = Toplevel()
self.tl.title("Tst")
self._entry_val = ''
self.frame = Frame(self.tl)
self.frame.pack()
self.label = Label(self.tl, text="Ввод:", fg="red")
self.label.pack(side=TOP)
self.entry = Entry(self.tl)
self.entry.focus_set()
self.entry.pack(side = TOP)
self.entry.bind("<Return>", self.onEnter)

def onEnter(self, event):
'''Процедура вызываемая на
нажатие Enter в поле entry формы'''
self._entry_val = self.entry.get()
if self._entry_val == '':
self._entry_val = 'empty'
self.tl.destroy()
return self._entry_val

def getEntryVal(self):
'''Возвращает символы введенные
в поле entry формы'''
return self._entry_val

if __name__ == '__main__':

class App(Tk):
def __init__(self):
Tk.__init__(self)
self.btn = Button(self, text = "Нажми меня!")
self.btn.bind("<ButtonPress-1>", self.start)
self.btn.pack(side = TOP)

def visio(self):
self.tl = EntryForm()

def prepareThr(self):
print "prepareThr() begin"
for i in xrange(10):
self.visio()
txt = ''
while 1:
txt = self.tl.getEntryVal()
if txt != '':
break
time.sleep(0.1)
print txt
#del(self.tl)
print "prepareThr() end"

def start(self, event):
print "start() begin"
thr = threading.Thread(target = self.prepareThr, name = "thr").start()
print "start() end"

t = App()
t.mainloop()



Отредактировано (Март 3, 2010 06:39:18)

Офлайн

#2 Март 3, 2010 06:41:19

somaniac
От:
Зарегистрирован: 2009-01-30
Сообщения: 22
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter, toplevel и потоки ЧЯДНТ?

неужели никто не сталкивался с подобным?



Офлайн

#3 Март 3, 2010 09:30:35

igor.kaist
От:
Зарегистрирован: 2007-11-12
Сообщения: 1879
Репутация: +  3  -
Профиль   Отправить e-mail  

Tkinter, toplevel и потоки ЧЯДНТ?

А что программа должна делать?
Данные между потоками лучше передавать через queue



Офлайн

#4 Март 3, 2010 09:32:34

DHT
От:
Зарегистрирован: 2009-09-24
Сообщения: 119
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter, toplevel и потоки ЧЯДНТ?

Чтобы не подвисало нужно отобразить Toplevel с его виджетами до того как туда начнут добавлять данные потоки.



Офлайн

#5 Март 3, 2010 09:59:28

somaniac
От:
Зарегистрирован: 2009-01-30
Сообщения: 22
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter, toplevel и потоки ЧЯДНТ?

Ну так проблема в том, что подвисания происходят случайным образом и даже в том случае если я просто создаю подряд несколько топлевел-окон и не дожидаюсь результатов ввода. Если же я заранее создаю окно и делаю ему withdraw, а потом в нужный момент вызываю deiconify, то подвисание происходит гарантированно на вызове deiconify



Офлайн

#6 Март 3, 2010 10:18:21

somaniac
От:
Зарегистрирован: 2009-01-30
Сообщения: 22
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter, toplevel и потоки ЧЯДНТ?

igor.kaist
А что программа должна делать?
Данные между потоками лучше передавать через queue
Программа в потоке занимается довольно долгим перелопачиванием данных, но в некоторые моменты нужно скорректировать этот процесс вводом вариантов в сплывающем окне. т.е. практически вся функциональность всплывающего топлевел-окна описана в вышеприведенном примере



Офлайн

#7 Март 3, 2010 10:48:21

Griffon
От: Ukrain, Zaporozhie
Зарегистрирован: 2009-03-04
Сообщения: 324
Репутация: +  11  -
Профиль   Отправить e-mail  

Tkinter, toplevel и потоки ЧЯДНТ?

Вообще не понятно что ссылается на первый созданный класс, после того как вы создали второй.
И не в этом ли проблема? Не знаю как ведёт себя питон в таком случае при созданном окне. Но если окно уничтожить, то скорее всего класс удалится сборщиком мусора. И соответственно произойдёт зацикливание в потоке. Или оба закроются по вводу во вторую форму.
Вот такое неуверенное предположение.

Может быть и зависания где-то на этом стыке?



Отредактировано (Март 3, 2010 10:51:49)

Офлайн

#8 Март 3, 2010 11:04:41

somaniac
От:
Зарегистрирован: 2009-01-30
Сообщения: 22
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter, toplevel и потоки ЧЯДНТ?

Griffon
Вообще не понятно что ссылается на первый созданный класс, после того как вы создали второй.
И не в этом ли проблема? Не знаю как ведёт себя питон в таком случае при созданном окне. Но если окно уничтожить, то скорее всего класс удалится сборщиком мусора. И соответственно произойдёт зацикливание в потоке. Или оба закроются по вводу во вторую форму.
Вот такое неуверенное предположение.

Может быть и зависания где-то на этом стыке?
Если выполнять del(self.tl) (в примере закомментирован), то поведение не меняется. И еще вызывает удивление тот момент, что если я вызываю deiconify для заранее созданного окна в основном классе, то без потока все работает замечательно, а вот если это сделать в потоке, то гарантированный “висяк”



Офлайн

#9 Март 3, 2010 11:18:21

Griffon
От: Ukrain, Zaporozhie
Зарегистрирован: 2009-03-04
Сообщения: 324
Репутация: +  11  -
Профиль   Отправить e-mail  

Tkinter, toplevel и потоки ЧЯДНТ?

Так может в этом удалении и проблема? Стоит попробовать хранить ссылки на созданные классы в списке.
self.tl +=
В начале потока определять длину и проверять self.tl.ххххххх. В конце потока удалить из списка.

Или просто tl без self. :)

А вообще если это окно будет вызываться программой автоматически, то может такое получится что вылитит сразу десяток окон, а если юзер отойдёт от машины то вообще хана. То есть надо контролировать что бы окно всегда было одно, а необходимые события добавлялись в очередь.



Отредактировано (Март 3, 2010 11:19:53)

Офлайн

#10 Март 3, 2010 12:49:43

somaniac
От:
Зарегистрирован: 2009-01-30
Сообщения: 22
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter, toplevel и потоки ЧЯДНТ?

Griffon
Так может в этом удалении и проблема? Стоит попробовать хранить ссылки на созданные классы в списке.
self.tl +=
В начале потока определять длину и проверять self.tl.ххххххх. В конце потока удалить из списка.

Или просто tl без self. :)

А вообще если это окно будет вызываться программой автоматически, то может такое получится что вылитит сразу десяток окон, а если юзер отойдёт от машины то вообще хана. То есть надо контролировать что бы окно всегда было одно, а необходимые события добавлялись в очередь.
Я попробую, но кажется все же, что проблема не в этом, иногда подвисание происходит при создании первого окна (при вызове в prepareThr self.visio()).



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version