python-3.x - 是否可以多进程 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()
预期结果:
- 弹出一个标题为“Window 1”的 tkinter 窗口
- 按下 START SESSION 后,“Window 1”被破坏(关闭)。
- “Window 2”(看起来完全一样)然后弹出,它的 START SESSION 按钮被禁用。
- 按右上角的十字关闭“窗口 2”并结束应用程序。
实际结果:
- 弹出一个标题为“Window 1”的 tkinter 窗口
- 按下 START SESSION 后,“Window 1”被破坏(关闭)。
- 然后弹出另一个“窗口 1”(看起来完全相同),启用其 START SESSION 按钮未映射到任何命令。
- 按右上角的十字关闭“窗口 1”并结束应用程序。
解决方案
这是可能的,但与 GUI 的所有交互都必须在一个进程中进行。Tkinter 本身不能跨越进程,也不能跨越线程。您的其他进程必须将工作放在 tkinter 进程定期轮询和操作的队列上(当然,您也可以与任何其他形式的 IPC 通信)。
这样做的原因是每个根窗口都与一个嵌入式 tcl 解释器相关联,而这个解释器本身不能跨越进程。
推荐阅读
- c++ - ifstream 在 x64 位平台上崩溃
- css - 为什么在尝试在开始时对齐 flex 项目时应用 flex-direction 列和 justify-content center 这不起作用?
- bcrypt - 从 Spring Security 5.x Bcrypt 哈希迁移到 Quarkus
- html - 使用 Bootstrap 更改平板设备上的布局顺序
- c++ - C ++ linux蓝牙sdp_connect仅以root权限成功
- javascript - 缺少 Javascript 休息参数
- java - 我是否做到不接受输入的@gmail、@hotmail、@yahoo 电子邮件?
- c++ - 使用 g++ 编译 Objective-C 项目时出现运行时错误
- python - 为多个特征运行 pdp.pdp_plot 并将输出轴放入新图形
- r - Broom::tidy 函数对 glm2 对象不起作用?