使用 Python 和 tkinter 进行多处理
Posted
技术标签:
【中文标题】使用 Python 和 tkinter 进行多处理【英文标题】:Multiprocessing with Python and tkinter 【发布时间】:2020-09-28 00:51:20 【问题描述】:这似乎微不足道,但我无法解释......
我有以下工作的 tkinter 代码 sim.py:
import tkinter as tk
import os
import random
import time
class MainApp(tk.Tk):
def __init__(self, parent=None, title="Device", *args, **kwargs):
super().__init__()
print("CHILD.GUI: Entered __init__")
self.title(title)
tk.Button(self, text="QUIT", command=self.on_quit).pack(side="top", padx=30, pady=30)
""" <RUN> """
self.mainloop()
def on_quit(self):
print("Quitting ...")
self.destroy()
def main():
root = MainApp()
def my_dev( kill_queue, child_conn):
print ("CHILD: Entered device function ...")
root = MainApp()
if __name__ == "__main__":
main()
# EOF sim.py
但是当我尝试从主程序 main.py 将其作为子程序执行时:
import multiprocessing as mp
import os
import sys
import time
import signal
import tkinter as tk
import sim
nproc = 1
result = 0
def signal_handler(signal, frame):
print ('\nCaught interrupt, cleaning up...')
print (process.terminate())
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
if __name__ == '__main__':
kill_queue = mp.Queue()
parent_connection, child_connection = mp.Pipe()
process = mp.Process(target=sim.my_dev, args=(kill_queue,child_connection,))
process.start()
print("Spawning process with PID:".format(process.pid) )
# finite number of runs ...
for dummy in range(100):
while parent_connection.poll():
result = parent_connection.recv()
print("Data: :8.2f".format(result), end="")
print("\r", end="")
time.sleep(.1)
# Finishing up ... sending a kill signal
print("\n\n")
kill_queue.put(True)
process.join()
print ('Main thread done.')
我什么也得不到。它打印“儿童:输入设备功能”,就是这样。 “儿童:GUI”不打印。没有错误。我可以看到 CHILD 进程与
ps ax
并在主程序完成时终止。
请注意,我已经删除了孩子中的 PIPE 部分……实际上,如果我去掉 GUI,那部分就可以工作了。
有什么想法吗?
谢谢你, 拉德克
编辑:修复(希望)父评论。还修复了窗口标题。它仍然没有运行。尝试冲洗...
编辑:在 my_dev 中打印后刷新,并且在 root = MainApp() 之后没有给出任何结果...
编辑:flush 做了一些事情(方便的小事)。我将 tkinter 添加到 main.py 中(只需 tk.Tk() 进行初始化)。突然,代码进入MainApp(显示:CHILD.GUI: Entered init)报错:
2020-06-09 01:15:45.982 python[50273:22418845] 无法从服务器检索字体!在本地注册系统字体...
顺便说一句,50273 是生成进程的正确 PID。
我还直接将我的 GUI 函数添加到 main.py ...同样的错误。该错误似乎与产生新进程有关......我没有找到任何解决方案......建议?回复>
【问题讨论】:
我再次检查:由于某种原因,CHILD 进程是僵尸(ps ax 中的 Z+)。我还是不明白。 R> 子进程中的控制台输出可能会被缓存,请尝试在每个打印语句后添加sys.stdout.flush()
。顺便说一句,tk.Tk()
没有父级,因此应删除 MainApp.__init__()
中的 parent
参数。
【参考方案1】:
所以有一个答案......有点。
该代码在 Debian Linux(准确地说是 Raspbian)上完美运行。
我的 Mac 上仍然收到有关缺少字体的错误消息:
2020-06-09 01:15:45.982 python[50273:22418845] Could not retrieve fonts from the server! Registering system fonts locally...
正如我上面提到的,它只在主程序中包含tk.Tk()
后出现在系统刷新中。
为了完整起见:我使用自制软件在我的 Mac 上安装了 pyenv
。所有 python3 包都是通过 pip 安装的。其他一切似乎都按预期工作。上面的 tkinter 代码在作为主程序执行时运行良好。任何时候通过多处理调用它都不起作用。
最终,我需要程序在 Linux 上运行;我使用我的 Mac 对非硬件部分(如 GUI)进行编码。如果它在 Mac 上也能正常工作,那就太好了。
建议?
和平! 拉德克
【讨论】:
以上是关于使用 Python 和 tkinter 进行多处理的主要内容,如果未能解决你的问题,请参考以下文章
Python多处理-TypeError:无法腌制'_tkinter.tkapp'对象