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
相关产品推荐
相关产品推荐

