Tkinter 中的多处理
Multiprocessing in Tkinter
我有以下代码,我在其中调用从小部件输入的按钮的函数。这是一个 运行 大约需要 4 分钟的函数,为了解决 tkinter window 的 'not responding' 问题,我想在不同的核心上获得 func 进程 运行ning 和终止,因为它可以通过应用程序 运行ning 在 mainloop 上使用不同的参数再次调用。我阅读了 multiprocessing 的文档, Pool 似乎是这里的选择,但我不知道如何在这里构建它。尝试了一些错误。
class database(tk.Tk):
def __init__(self, *args, *kwargs):
tk.Tk.__init__(self, *args, **kwargs):
container= tk.Frame(self, width=1000, height=1000)
container.pack(side="top", fill="both", expand= True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in ( msPage): #many more pages here
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(msPage)
def show_frame(self,cont):
frame = self,frames[cont]
frame.tkraise()
def MarkS(msVar):
ms.func(msVar.get()) # func takes about 4 mins
class msPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
msVar = StringVar()
msCal = Calendar(self, selectmode='day'
textvariable=msVar).pack(fill="both", expand=True)
# button2 calls MarkS
button2 = ttk.Button(self,
text="Get Data",
command=lambda: MarkS(msVar)).pack(pady=30, padx=10)
app = database()
app.geometry("1066x568")
app.minsize(width=670, height=550)
app.mainloop()
这是一个独立示例,可以帮助您入门:
from multiprocessing import Process
class ms_var_class():
value = None
def __init__(self, value):
self.value = value
def get(self):
return self.value
# This is to simulate type(ms)
class ms_class():
process = None
# This is for simulating your long running function
def func(self, ms_var):
print(ms_var)
def MarkS(msVar):
ms.process = Process(target=ms.func, args=(msVar.get(),))
ms.process.start()
# Call ms.process.join() later
ms_var = ms_var_class("bogus")
ms = ms_class()
MarkS(ms_var)
if ms.process is not None:
ms.process.join()
感谢 Mike 的评论并帮助我找到解决方案
这是我的做法
创建全局队列
q= queue.Queue()
在 class msPage
中定义了函数 MarkS
def MarkS(msVar):
q.put([7 , datetime.datetime.strptime(msVar.get(), '%x').strftime('%d-%b-%Y').upper(),0])
ThreadedTask(q).start()
7 是我为每个页面设置的 9 个函数的唯一编号 (class)
制作了另一个 class 的 ThreadedTask,如下面的 link
Tkinter: How to use threads to preventing main event loop from "freezing"
class ThreadedTask(threading.Thread):
def __init__(self,queue):
threading.Thread.__init__(self)
q = queue
def run(self):
items = q.get()
if items[0]==7:
ms.func(items[1])
ThreadedTask(q).start() 创建一个构造函数对象,运行 函数根据此处的参数自动启动,这当然是 q 的第一个元素,在我的例子中是 3 的列表.它被检测到并且所需的功能是另一个线程中的 运行 以防止 tkinter window 关闭。
希望对您有所帮助! :)
我有以下代码,我在其中调用从小部件输入的按钮的函数。这是一个 运行 大约需要 4 分钟的函数,为了解决 tkinter window 的 'not responding' 问题,我想在不同的核心上获得 func 进程 运行ning 和终止,因为它可以通过应用程序 运行ning 在 mainloop 上使用不同的参数再次调用。我阅读了 multiprocessing 的文档, Pool 似乎是这里的选择,但我不知道如何在这里构建它。尝试了一些错误。
class database(tk.Tk):
def __init__(self, *args, *kwargs):
tk.Tk.__init__(self, *args, **kwargs):
container= tk.Frame(self, width=1000, height=1000)
container.pack(side="top", fill="both", expand= True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in ( msPage): #many more pages here
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(msPage)
def show_frame(self,cont):
frame = self,frames[cont]
frame.tkraise()
def MarkS(msVar):
ms.func(msVar.get()) # func takes about 4 mins
class msPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
msVar = StringVar()
msCal = Calendar(self, selectmode='day'
textvariable=msVar).pack(fill="both", expand=True)
# button2 calls MarkS
button2 = ttk.Button(self,
text="Get Data",
command=lambda: MarkS(msVar)).pack(pady=30, padx=10)
app = database()
app.geometry("1066x568")
app.minsize(width=670, height=550)
app.mainloop()
这是一个独立示例,可以帮助您入门:
from multiprocessing import Process
class ms_var_class():
value = None
def __init__(self, value):
self.value = value
def get(self):
return self.value
# This is to simulate type(ms)
class ms_class():
process = None
# This is for simulating your long running function
def func(self, ms_var):
print(ms_var)
def MarkS(msVar):
ms.process = Process(target=ms.func, args=(msVar.get(),))
ms.process.start()
# Call ms.process.join() later
ms_var = ms_var_class("bogus")
ms = ms_class()
MarkS(ms_var)
if ms.process is not None:
ms.process.join()
感谢 Mike 的评论并帮助我找到解决方案
这是我的做法
创建全局队列
q= queue.Queue()
在 class msPage
中定义了函数 MarkSdef MarkS(msVar):
q.put([7 , datetime.datetime.strptime(msVar.get(), '%x').strftime('%d-%b-%Y').upper(),0])
ThreadedTask(q).start()
7 是我为每个页面设置的 9 个函数的唯一编号 (class) 制作了另一个 class 的 ThreadedTask,如下面的 link Tkinter: How to use threads to preventing main event loop from "freezing"
class ThreadedTask(threading.Thread):
def __init__(self,queue):
threading.Thread.__init__(self)
q = queue
def run(self):
items = q.get()
if items[0]==7:
ms.func(items[1])
ThreadedTask(q).start() 创建一个构造函数对象,运行 函数根据此处的参数自动启动,这当然是 q 的第一个元素,在我的例子中是 3 的列表.它被检测到并且所需的功能是另一个线程中的 运行 以防止 tkinter window 关闭。
希望对您有所帮助! :)