Tkinter如何从其他文件打开新窗口,点击按钮仅能打开一次如何解决
Tkinter多窗口只能打开一次问题修复方案
核心原因
你通过import ger_dentista/import ger_pacientes的方式触发窗口创建,Python的模块导入机制只会在首次调用import时执行模块内的全局代码,后续import会直接读取缓存的模块对象,不会重新执行代码,因此窗口只能打开一次。
修复步骤
第一步:改造子窗口模块
不要把窗口初始化代码直接写在子模块的全局作用域,也不要在子模块创建新的Tk()实例,统一封装为函数、使用Toplevel创建子窗口:
ger_dentista.py示例
from tkinter import * def abrir_janela_dentista(root_principal): # 子窗口使用Toplevel继承主窗口上下文,不要新建Tk()实例 janela = Toplevel(root_principal) janela.title("Gerenciar Dentistas") janela.geometry("600x400") # 此处替换为你原本的窗口组件代码 Label(janela, text="牙医管理界面").pack(pady=20) # 不要在子模块写mainloop,主窗口已存在全局mainloop
ger_paciente.py示例
from tkinter import * def abrir_janela_paciente(root_principal): janela = Toplevel(root_principal) janela.title("Gerenciar Pacientes") janela.geometry("600x400") # 此处替换为你原本的窗口组件代码 Label(janela, text="患者管理界面").pack(pady=20)
第二步:改造主文件main.py
将模块导入放到文件头部,点击按钮时直接调用子模块封装好的窗口创建函数即可:
from tkinter import * from tkinter import ttk # 模块导入统一放到文件头部 import ger_dentista import ger_pacientes root = Tk() class funcoes(): def janela2(self): # 调用子模块函数传入主窗口实例,触发子窗口创建 ger_dentista.abrir_janela_dentista(self.root) def janela3(self): ger_pacientes.abrir_janela_paciente(self.root) class application(funcoes): def __init__(self): self.root = root self.tela() self.frames_da_tela() self.widgets_frame() root.mainloop() def tela(self): self.root.title('ODONTO DIGITAL') self.root.configure(background='#483D8B') self.root.geometry('800x600') self.root.resizable(True, True) self.root.minsize(width=600, height=480) def frames_da_tela(self): self.frame_1 = Frame(self.root) self.frame_1.place(relx= 0.25, rely= 0.25, relwidth= 0.50, relheight= 0.46) def widgets_frame(self): self.bt_dentista = Button(self.frame_1, text='Gerenciar dentistas', command=self.janela2) self.bt_dentista.place(relx=0.3, rely=0.21, relwidth=0.35, relheight=0.12) self.bt_paciente = Button(self.frame_1, text='Gerenciar pacientes', command=self.janela3) self.bt_paciente.place(relx=0.3, rely=0.34, relwidth=0.35, relheight=0.12) self.bt_consulta = Button(self.frame_1, text='Gerenciar Consultas') self.bt_consulta.place(relx=0.3, rely=0.48, relwidth=0.35, relheight=0.12) # 退出按钮新增关闭主窗口逻辑 self.bt_sair = Button(self.frame_1, text='Sair', command=self.root.destroy) self.bt_sair.place(relx=0.3, rely=0.62, relwidth=0.35, relheight=0.12) self.lb_pesquisar = Label(self.frame_1, text='O que deseja fazer?') self.lb_pesquisar.place(relx=0.32 , rely=0.04) application()
注意事项
- 整个Tkinter程序只能保留一个主
Tk()实例和一个全局mainloop,多实例会导致上下文异常,Linux窗口管理器下兼容性问题会更明显 - 不要在函数内部执行模块导入,避免模块缓存机制导致的逻辑异常
内容的提问来源于stack exchange,提问作者Ullysses Vieira
相关产品推荐
相关产品推荐

