Reputation: 69
here is my code:
# -*- coding:utf-8 -*-
import time
import tkinter as tk
from multiprocessing import Pool
class Application(tk.Tk):
def __init__(self):
super(self.__class__, self).__init__()
self.title('test')
self.geometry('300x500')
self.main_ui()
self.pool = Pool(10)
def a(self, word):
print(word, ' start')
time.sleep(5)
print(word, 'end')
def call_a(self, word):
self.pool.apply_async(self.a, (word,))
def main_ui(self):
bnt1 = tk.Button(self, text='a', command=lambda: self.call_a('a'))
bnt1.place(x=0, y=0, height=100, width=70)
bnt1 = tk.Button(self, text='b', command=lambda: self.call_a('b'))
bnt1.place(x=0, y=100, height=100, width=70)
# pass
def main():
app = Application()
app.mainloop()
if __name__ == '__main__':
main()
l would like let print(word, ' start')
and print(word, ' start')
in other processing without blocking process of tkinter, because time.sleep(5)
with block process of tkinter. As i think that two process won;t be enough, so i use a processing pool.but the program does not work this time(when i push button, def a(self,word)
do not work).
the gui can show correctly, but when i push the button, def a(self, word):
is not working, i don't why and how to fix the problem.
By the way, i'm using python3.
Thank you
Upvotes: 0
Views: 737
Reputation: 311328
You cannot ignore the return value of multiprocessing.Pool.apply_async
. It's not designed as a fire-and-forget mechanism for running "background" tasks. If you modify your code to check the result:
def call_a(self, word):
res = self.pool.apply_async(self.a, (word,))
ret = res.get()
print("return value:", ret)
What you will see when you click on the a
button is:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib64/python3.10/tkinter/__init__.py", line 1921, in __call__
return self.func(*args)
File "/home/lars/tmp/python/gui.py", line 25, in <lambda>
bnt1 = tk.Button(self, text="a", command=lambda: self.call_a("a"))
.
.
.
TypeError: cannot pickle '_tkinter.tkapp' object
So, the problem is that your call to apply_async
is failing with an exception, but you were never retrieving it. The failure is caused by the fact that apply_async
attempts to pickle objects in order to send them to the worker, but that's not possible with a Tk application object.
To make your code work probably requires a some re-architecture: for example, rather than trying to use multiprocessing.Pool
, consider manually spawning a number of processes (or threads!), and then using a queue to pass data to the workers.
Upvotes: 2