Tkinter能否通过winfo_id初始化变量实现跨进程控制同一窗口
跨进程通过winfo_id初始化Tk实例接管窗口的方案完全不可行
核心原因如下:
tk.Tk()构造函数的入参不接收操作系统层面的窗口ID,它的第一个位置参数是screenName,用来指定Tk实例连接的显示服务标识,传入你拿到的win_id不会触发任何“接管现有窗口”的逻辑,只会要么抛出参数错误,要么直接创建一个全新的独立根窗口,完全达不到你预期的效果。- Tkinter的窗口对象和创建它的进程、进程内的Tcl解释器实例是强绑定的,底层窗口资源的所有权完全归属创建它的Tcl上下文,其他进程没有办法把自己进程内的Tk实例绑定到这个外部窗口上。跨进程给原生窗口发系统级消息(比如移动、关闭、改标题)是可以做到的,但不可能让另一个进程的Tk把这个窗口当成自己的根窗口,完成添加控件、绑定事件、跑UI事件循环这类Tk层面的操作。
- 你在main.py里调用
window.withdraw()只是把窗口隐藏,这个窗口的事件循环、资源句柄都还留在main.py进程中,second.py就算拿到了窗口ID,也没有对应的Tcl上下文权限去操控这个窗口的Tk属性,强行操作大概率会直接导致两个进程的UI线程崩溃、窗口无响应。
如果要实现两个进程协作控制UI的需求,可以参考这两个可行方向:
- 把所有Tk UI相关的逻辑全部放在同一个进程里,另一个进程只负责计算、IO等耗时任务,两个进程通过管道、消息队列、本地socket做进程间通信,耗时任务把需要更新UI的指令发给UI所在进程,由UI进程自己完成窗口、控件的操作。
- 如果只需要做窗口移动、缩放、置顶、关闭、修改标题这类基础操作,不需要往窗口里加Tk控件,可以直接调用系统原生窗口API(Windows下用pywin32的win32gui模块、Linux下用Xlib相关库)操作拿到的窗口ID,不需要在第二个进程里初始化Tk实例。
内容的提问来源于stack exchange,提问作者danilo
相关产品推荐
相关产品推荐

