You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python桌面应用模块与类开发咨询:表单重复打开问题及实现合理性验证

Hey there! Let's break down your questions step by step—since you're new to Python and Tkinter, I'll keep things super straightforward.


1. Why are two copies of each form opening?

You're seeing duplicate windows for two key reasons:

  • You're manually calling __init__ twice: When you write link_2.ClassLink_2(root).__init__(root), the ClassLink_2(root) part already triggers the __init__ method automatically (Python runs __init__ whenever you create a class instance). Then you call __init__(root) again, which runs openNewWindow() twice—hence two windows.
  • Multiple Tk() instances: Each of your .py files creates its own root = Tk() instance. Tkinter is designed to have only one main Tk instance at a time. Extra Tk instances cause hidden background windows and unexpected behavior, even if you use root.withdraw().

2. Is your current form implementation reasonable?

It works, but there are several easy fixes to make it cleaner, more maintainable, and aligned with Tkinter best practices:

  • Don't create a Tk() instance in every module—only one main instance in your entry file (link_1.py).
  • Never manually call __init__ after instantiating a class.
  • Use if __name__ == "__main__" to wrap your entry code (prevents code from running when you import the module elsewhere).
  • Avoid from tkinter import * (it causes name conflicts; better to import specific components).

Fixed Code Examples

Here's how to adjust your files to fix both issues:

link_1.py (Entry File)

This is the only file that creates the main Tk instance:

from tkinter import Tk
import link_2

class ClassLink_1:
    def __init__(self):
        print("in link_1 __init__ instruction")

    def call_function(self):
        print("in call_function")

# Only run this code when we execute link_1.py directly
if __name__ == "__main__":
    print("in link_1")
    
    # Single main Tk instance
    root = Tk()
    root.withdraw()  # Hide the main blank window
    
    # Correct way to instantiate ClassLink_2 (no manual __init__ call)
    link_2.ClassLink_2(root)
    
    # Run your test function
    ClassLink_1().call_function()
    
    root.mainloop()

Receives the main Tk instance as a parameter instead of creating its own:

from tkinter import Toplevel, Button, Label
import link_3

class ClassLink_2:
    def __init__(self, master):
        self.master = master  # Store the main window instance
        self.openNewWindow()

    def openNewWindow(self):
        # Use the main window as parent for the new Toplevel
        newWindow = Toplevel(self.master)
        newWindow.title("Title opened from link_1")
        newWindow.geometry("500x500")
        Label(newWindow, text="Opened from link_1").grid(row=1, column=1)
        self.add_button = Button(newWindow, text="in ClassLink_2", command=self.do_add)
        self.add_button.grid(row=3, column=1)

    def do_add(self):
        print("button pressed")
        # Pass the main window to ClassLink_3
        link_3.ClassLink_3(self.master)

Same pattern as link_2.py—uses the shared main window instance:

from tkinter import Toplevel, Button, Label

class ClassLink_3:
    def __init__(self, master):
        self.master = master
        self.openNewWindow()

    def openNewWindow(self):
        newWindow = Toplevel(self.master)
        newWindow.title("Title opened from link_2")
        newWindow.geometry("500x500")
        Label(newWindow, text="Opened from link_2").grid(row=1, column=1)
        self.add_button = Button(newWindow, text="in ClassLink_3", command=self.do_add)
        self.add_button.grid(row=3, column=1)

    def do_add(self):
        print("button pressed")
        # When you add link_4, pass self.master here too
        # link_4.ClassLink_4(self.master)

内容的提问来源于stack exchange,提问作者egginstone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:43:14