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

Tkinter类嵌套多窗口问题:子窗口控件显示异常及扩展咨询

问题解决与优化方案

1. 新窗口控件显示在主窗口的原因及修复

核心问题是创建新窗口控件时未指定父窗口,tkinter默认会将主窗口作为所有未指定父组件的控件容器,导致按钮跑到主窗口里。同时,打开新窗口不应使用Tk(),一个tkinter程序建议仅保留一个主Tk()实例,子窗口需用Toplevel()。

修改后的完整代码

from tkinter import *

class Uygulama(object):
    def __init__(self, parent):
        self.parent = parent
        self.araclar()

    def araclar(self):
        self.etiket1 = Label(self.parent, text="WELCOME TO MY PROGRAM", fg="blue", font="Times 15 bold", bg="grey")
        self.etiket1.pack()

        self.etiket2 = Label(self.parent, text="Hello world", fg="black", font="Times 11 bold", bg="grey")
        self.etiket2.place(rely=0.95, relx=0.70)
     
        self.dugme5 = Button(self.parent, text="click here to open new window", command=self.bk4, fg="black", bg="blue", font="bold")
        self.dugme5.place(relx=0.38, rely=0.78)

    def bk4(self):
        # 创建依附于主窗口的子窗口
        pencere2 = Toplevel(self.parent)
        pencere2.title("This is a new window")
        pencere2.geometry("390x350+860+30")
        pencere2.resizable(width=False, height=False)
        pencere2.configure(bg="grey")
        # 将子窗口传入Uygulama2作为控件父容器
        uyg2 = Uygulama2(pencere2)

class Uygulama2:
    def __init__(self, parent):
        self.parent = parent
        self.araclar2()

    def araclar2(self):
        # 明确指定父窗口为新创建的Toplevel
        self.dugme6 = Button(self.parent, text="click for printing", command=self.bk5, fg="black", bg="red", font="bold")
        self.dugme6.place(relx=0.5, rely=0.5, anchor=CENTER)

    def bk5(self):
        print("hello world")

if __name__ == "__main__":
    pencere = Tk()
    pencere.title("This is main window")
    pencere.geometry("550x550+300+30")
    pencere.resizable(width=False, height=False)
    pencere.configure(bg="grey")
    uyg = Uygulama(pencere)
    pencere.mainloop()

关键改动说明

  • 所有控件创建时明确指定parent参数,确保控件归属对应窗口。
  • 用Toplevel()替代Tk()创建新窗口,它依附于主窗口,共享同一事件循环,避免多主窗口的异常问题。
  • 将Uygulama2类移到外部,代码结构更清晰,便于后续扩展。

2. 添加更多控件不影响主窗口

只要在Uygulama2的方法中创建新控件时,始终将self.parent作为父容器,所有控件都会被限制在新窗口内,完全不会干扰主窗口。例如:

def araclar2(self):
    self.dugme6 = Button(self.parent, text="click for printing", command=self.bk5, fg="black", bg="red", font="bold")
    self.dugme6.place(relx=0.5, rely=0.5, anchor=CENTER)
    
    # 新增标签仅显示在新窗口
    self.etiket3 = Label(self.parent, text="New Window Exclusive Content", fg="white", bg="grey", font="Times 12")
    self.etiket3.pack(pady=20)

3. 打开第三个基于类的窗口

完全可以用相同逻辑实现。在Uygulama2中添加按钮,点击后创建新的Toplevel窗口并实例化对应的第三个类即可:

扩展示例代码

class Uygulama3:
    def __init__(self, parent):
        self.parent = parent
        self.araclar3()

    def araclar3(self):
        Label(self.parent, text="Third Window", font="Times 14 bold", bg="grey").pack(pady=10)
        Button(self.parent, text="Close Window", command=self.parent.destroy).pack(pady=5)

# 扩展Uygulama2,添加打开第三个窗口的功能
class Uygulama2:
    def __init__(self, parent):
        self.parent = parent
        self.araclar2()

    def araclar2(self):
        self.dugme6 = Button(self.parent, text="click for printing", command=self.bk5, fg="black", bg="red", font="bold")
        self.dugme6.place(relx=0.5, rely=0.4, anchor=CENTER)
        
        # 新增打开第三个窗口的按钮
        self.dugme7 = Button(self.parent, text="Open Third Window", command=self.open_third_window, bg="green", fg="white", font="bold")
        self.dugme7.place(relx=0.5, rely=0.6, anchor=CENTER)

    def bk5(self):
        print("hello world")
    
    def open_third_window(self):
        pencere3 = Toplevel(self.parent)
        pencere3.title("Third Window")
        pencere3.geometry("300x200+600+200")
        pencere3.configure(bg="grey")
        uyg3 = Uygulama3(pencere3)

点击第二个窗口的按钮即可打开独立的第三个窗口,所有窗口控件相互独立,不会产生交叉影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 02:25:17