首页 > 解决方案 > 是否可以多进程 tkinter?

问题描述

我正在尝试多处理多个 tkinter 窗口,其中每个进程中都需要线程(对于带有 while 循环的长时间运行的进程)。这可能吗?

我试图通过做一个纯多线程实现来解决这个问题——整个应用程序开始变得“​​滞后”;因此现在尝试进行多处理。请参阅我正在尝试做的非常简化的基本版本的代码。有2个脚本:

主文件(运行)

from tkinter import *
from tkinter import ttk
import threading
import multiprocessing
import multiprocessing_import_worker

def hello():
    if __name__ == '__main__':
        p_list = ["Hello", "success"]
        p = multiprocessing.Process(target=multiprocessing_import_worker.worker, args=p_list)
        p.start()
        root.destroy()

root = Tk()
root.title("Window 1")

statusFrame = Frame(root)
statusFrame.pack()
statusLabelFrame = LabelFrame(statusFrame, text='TEST FRAME', font="Helvetica 8 bold")
statusLabelFrame.pack(fill="both", expand="yes", padx="7")
firstButtonFrame = Frame(root)
firstButtonFrame.pack()
statusbar = Label(statusLabelFrame, text="TEST", width=40, font="Helvetica 8 bold")
statusbar.pack()
b1=ttk.Button(firstButtonFrame, text="START SESSION", width=15, command=hello)
b1.pack(pady=(10,0))

root.mainloop()

辅助文件(作为单独的进程运行)

def worker(word, word2):
    import threading
    import tkinter as tk
    from tkinter import ttk
    import os

    print(word)
    print(word2)

    def testThread():
        global word
        global word2
        print(word)
        print(word2)

    root = tk.Tk()
    root.withdraw()
    rootWindow = tk.Toplevel()
    rootWindow.title("Window 2")

    statusFrame = tk.Frame(rootWindow)
    statusFrame.pack()
    statusLabelFrame = tk.LabelFrame(statusFrame, text='TEST FRAME', font="Helvetica 8 bold")
    statusLabelFrame.pack(fill="both", expand="yes", padx="7")
    firstButtonFrame = tk.Frame(rootWindow)
    firstButtonFrame.pack()
    statusbar = tk.Label(statusLabelFrame, text="TEST", width=40, font="Helvetica 8 bold")
    statusbar.pack()
    b1=ttk.Button(firstButtonFrame, text="START SESSION", width=15, state='disabled')
    b1.pack(pady=(10,0))

    child_thread1 = threading.Thread(target=testThread)
    child_thread1.start()

    rootWindow.protocol("WM_DELETE_WINDOW", os._exit(0))
    rootWindow.mainloop()

预期结果

实际结果

标签: python-3.xmultithreadingtkintermultiprocessing

解决方案


这是可能的,但与 GUI 的所有交互都必须在一个进程中进行。Tkinter 本身不能跨越进程,也不能跨越线程。您的其他进程必须将工作放在 tkinter 进程定期轮询和操作的队列上(当然,您也可以与任何其他形式的 IPC 通信)。

这样做的原因是每个根窗口都与一个嵌入式 tcl 解释器相关联,而这个解释器本身不能跨越进程。


推荐阅读