Уведомления

Группа в Telegram: @pythonsu

#1 Март 3, 2010 15:50:21

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

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

Видимо не в этом. Еще вижу что фокус ставится до того как виджет появится на окне. А так больше ничего и не вижу.

Ещё вопрос. Зачем создавать отдельный поток для возврата значения? Вроде вызов колбек функции для этого лучше подходит.



Офлайн

#2 Март 4, 2010 09:24:02

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

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

Griffon
Видимо не в этом. Еще вижу что фокус ставится до того как виджет появится на окне. А так больше ничего и не вижу.

Ещё вопрос. Зачем создавать отдельный поток для возврата значения? Вроде вызов колбек функции для этого лучше подходит.
Ну с проблемой вызова окна разобрался, оказывается дергать GUI желательно из главного потока, если дергать из потоков, то возникают различные глюки, в частности при переходе на python 2.6 toplevel-окна вообще перестали создаваться нормально. Поэтому юзаю widget.after(ms, function) и в колбек функции создаю окно.
Но а вот момент про возврат значения через колбек не совсем понял. Можно подробности?



Офлайн

#3 Март 4, 2010 12:21:23

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

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

Остановился на таком вот варианте. Работает, но буду рад критике

class EntryForm():
'''Форма ввода'''
def __init__(self, root = None, pict='', clb_func = None):
self.clb_func = clb_func
self.tl = Toplevel(root)
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()
if self.clb_func:
self.clb_func(self._entry_val)
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)
self.queue = Queue.Queue()
self.visio()
self.res = ''

def visio(self):
#print "visio start"
#print self.queue.qsize()
while self.queue.qsize():
try:
msg = self.queue.get()
print "Queue get"
self.tl = EntryForm(root = self, clb_func = msg)
except Queue.Empty:
print "pass"
pass
self.after(100, self.visio)

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

class work():
def __init__(self, queue):
self.res = ''
self.queue = queue
print self.queue

def set_val(self, val):
self.res = val

def prepareThr(self):
print "prepareThr() begin"
for i in xrange(10):
self.queue.put(self.set_val)
while 1:
txt = self.res
if txt != '':
self.res = ''
break
time.sleep(0.1)
print txt
print "prepareThr() end"

t = App()
wrk = work(t.queue)
t.mainloop()



Офлайн

#4 Март 4, 2010 13:00:03

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

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

Пример.

class Some_toplevel_window():
def __init__(self, func):
...
def onEnter(self, event):
self.func(self.user_data)
...

class Some_class:
...
def callback(self, user_data):
# Do what i whant.
...
def some_func(self):
Some_toplevel_window(self.callback)
То есть мне не надо создавать поток только для того что бы проверять “А ввёл ли юзер данные?”. Вызывается функция? Значит юзер данные ввёл.



Офлайн

#5 Март 4, 2010 13:02:54

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

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

Какой смысл в этом:

        def prepareThr(self):
print "prepareThr() begin"
for i in xrange(10):
self.queue.put(self.set_val)
while 1:
txt = self.res
if txt != '':
self.res = ''
break
time.sleep(0.1)
print txt
print "prepareThr() end"
Когда после вызова set_val обязательно(!) проверка будет успешной. А без вызова set_val проверка будет не успешной.
То есть добавлять полученые данные к списку, выводить, сохранять надо в функции set_val. А поток вообще не надо создавать.



Офлайн

#6 Март 4, 2010 15:47:49

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

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

Griffon
Какой смысл в этом:
        def prepareThr(self):
print "prepareThr() begin"
for i in xrange(10):
self.queue.put(self.set_val)
while 1:
txt = self.res
if txt != '':
self.res = ''
break
time.sleep(0.1)
print txt
print "prepareThr() end"
Когда после вызова set_val обязательно(!) проверка будет успешной. А без вызова set_val проверка будет не успешной.
То есть добавлять полученые данные к списку, выводить, сохранять надо в функции set_val. А поток вообще не надо создавать.
Тут не совсем, то :) Этот поток просто что бы что то “крутилось”, на самом деле в этой функции идет обработка данных (идет долго и нудно), и вот эта обработка иногда прерывается, до тех пор пока не будет введено во всплывающем окне корректирующее значение. Если бы вся обработка которую я запихнул в потоки происходила за пару секунд, то вообще бы обошелся без потоков.



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version