Форум сайта python.su
14
к сожалению все примеры что нашел в гугле не рассматривают мою ситуацию а переписывать овер 500 строк кода на 80% слишком муторно посему прошу вашей помощи
побыстрому набросал более простой код с аналогичной ситуацией , вот он :
#!/usr/bin/python #-*- coding: utf-8 -*- import multiprocessing , time from Tkinter import * ### любая глобальная переменная global some_var , var2 some_var = 'lol' var2 = True ### любая функция def somefunc(): return 'aaa' class someclass(object): def __init__(self): ### любая переменная в конструкторе self.do = 'initalize' ### создаем в ткинтере примитивный гуй self.root = Tk() self.root.geometry('300x300+100+100') self.frm = Frame(self.root) self.frm.place(x = 0 , y = 0 , width = 300 , height = 300) # кнопка которая должна запустить процесс self.butt = Button(self.root , text = 'test multiprocessing' , command = self.button_command) self.butt.place(x = 10 , y = 10) # то что должно обрабатываться процессом self.txt = Text(self.root) self.txt.place(x = 10 , y = 50 , width = 280 , height = 240) # метод запускаемая в процессе def testfunc(self): self.gprint(self.do) writestr = some_var + somefunc() + '\n' for x in xrange(0 , 100) : self.gprint( str(x) + ') ' + writestr) time.sleep(0.1) var2 = False # меняю значение глобальной переменной # пишет в text виджет (self.txt) def gprint(self , value): self.txt.insert(END, value) self.txt.see(END) # перемотка к концу выхлопа # метод вызываеться при нажатии на кнопку и должна запустить в отдельном процессе метод testfunc def button_command(self): proc = multiprocessing.Process(target = self.testfunc) proc.start() if __name__ == '__main__' : w = someclass() w.root.mainloop()
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1470, in __call__
return self.func(*args)
File "C:\Users\shipper\Documents\Aptana Studio 3 Workspace\temp\python.su.py", line 51, in button_command
proc.start()
File "C:\Python27\lib\multiprocessing\process.py", line 130, in start
self._popen = Popen(self)
File "C:\Python27\lib\multiprocessing\forking.py", line 277, in __init__
dump(process_obj, to_child, HIGHEST_PROTOCOL)
File "C:\Python27\lib\multiprocessing\forking.py", line 199, in dump
ForkingPickler(file, protocol).dump(obj)
File "C:\Python27\lib\pickle.py", line 224, in dump
self.save(obj)
File "C:\Python27\lib\pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "C:\Python27\lib\pickle.py", line 419, in save_reduce
save(state)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\multiprocessing\forking.py", line 67, in dispatcher
self.save_reduce(obj=obj, *rv)
File "C:\Python27\lib\pickle.py", line 401, in save_reduce
save(args)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 548, in save_tuple
save(element)
File "C:\Python27\lib\pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "C:\Python27\lib\pickle.py", line 419, in save_reduce
save(state)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 725, in save_inst
save(stuff)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 725, in save_inst
save(stuff)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 725, in save_inst
save(stuff)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 313, in save
(t.__name__, obj))
PicklingError: Can't pickle 'tkapp' object: <tkapp object at 0x019BF1A8>
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Python27\lib\multiprocessing\forking.py", line 381, in main
self = load(from_parent)
File "C:\Python27\lib\pickle.py", line 1378, in load
return Unpickler(file).load()
File "C:\Python27\lib\pickle.py", line 858, in load
dispatch[key](self)
File "C:\Python27\lib\pickle.py", line 880, in load_eof
raise EOFError
EOFError
Офлайн
58
Помочь то оно не сложно, но тема должна то быть не здесь 
А если серьезно, то разделение на отдельные потоки в Tkinter выполняется совершенно другим образом. Что threding, что multiprocessing тут не помогут.
Офлайн
14
Помочь то оно не сложно, но тема должна то быть не здесь
А если серьезно, то разделение на отдельные потоки в Tkinter выполняется совершенно другим образом. Что threding, что multiprocessing тут не помогут.
Офлайн
58
Что во второй фразе Вас смутило? Механизм создание отдельного потока событий в Tkinter осуществляется без использования threading и multiprocessing. Если использовать их, то все равно на выходе получаем подвисание основного потока событий.
P.S. Я так и не понял, что Вам надо. Вы хотите, чтобы можно было запустить задачу, которая бы выполнялась в отрыве от основного потока событий. При этом не было подвисания GUI и можно было бы выполнять остальные задачи. Я Вас правильно понял?
Офлайн
14
абсолютно верно , только что можно сделать отдельный поток через ткинтер я никогда и не слышал , а как это делаеться на практике и вовсе понятия не имею
Офлайн
58
Для этого нужно использовать рекурсию с конструкцией .afer()
Пример
# -*- coding: utf-8 -*- import Tkinter import time # tm = time.time() def call_passive(event): print u"Выполнен шаг процесса." # Будет запускаться 10 секунд через каждую секунду if time.time() - tm < 10: root.after(1000, call_passive, event) # def call_active(event): print u"Пассивное нажатие в процессе." # def keybind(event): print u"Нажата клавиша - ", event.keysym # root = Tkinter.Tk() root.geometry("400x400+100+100") root.bind("<Any-KeyRelease>", keybind) # bt_free = Tkinter.Button(root, width=20, text="Свободно нажимаем") bt_free.place(relx=0.5, rely=0.33, anchor="center") bt_free.bind("<ButtonRelease-1>", call_active) # bt_proc = Tkinter.Button(root, width=20, text=u"Запускаем процесс") bt_proc.place(relx=0.5, rely=0.66, anchor="center") bt_proc.bind("<ButtonRelease-1>", call_passive) # root.mainloop()
Офлайн
14
код поразил , сейчас уже реализовал на мукльтипроцессинге заставив код работать не в классе а с обьектом класса , в следующем проекте буду ковырять , сенкс
Офлайн