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

如何精简两个相似tkinter窗口的实现函数,应使用类还是函数?

Tkinter重复窗口逻辑重构方案

你这两个窗口的布局逻辑完全一致,仅存在少量配置项差异,优先推荐用类封装公共逻辑,相比函数封装后续扩展更灵活,也能避免图片引用丢失、嵌套函数作用域混乱等问题。

可抽离的差异项

两个窗口的不同点仅有6项,完全可以作为参数传入公共逻辑:

  • 窗口标题
  • 顶部展示的图片路径
  • 用户名输入框的标签文本
  • 密码输入框的标签文本
  • 提交按钮的显示文本
  • 提交操作触发的回调函数

重构后代码(类实现,更推荐)

from tkinter import * 
import sys

class AuthWindow(Tk):
    def __init__(self, title, img_path, username_label, password_label, btn_text, submit_callback):
        super().__init__()
        # 基础窗口配置
        self.title(title)
        self.geometry('300x300')
        self.submit_callback = submit_callback

        # 组件创建
        label_hidden = Label(self, text="")
        # 图片存为实例属性避免被垃圾回收导致不显示
        self.photo = PhotoImage(file=img_path)
        photo_label = Label(self, image=self.photo)
        label_hidden_1 = Label(self, text="")
        username_label_widget = Label(self, text=username_label, font=('arial', 10, 'bold'))
        self.username_entry = Entry(self, width=40)
        label_hidden_2 = Label(self, text="")
        password_label_widget = Label(self, text=password_label, font=('arial', 10, 'bold'))
        self.password_entry = Entry(self, width=40, show='*')
        label_hidden_3 = Label(self, text="")

        submit_btn = Button(self, text=btn_text, width=20, height=1, font=('arial', 10, 'bold'), command=self.on_submit)
        self.password_entry.bind('<Return>', self.on_submit)

        # 布局
        label_hidden_1.pack()
        photo_label.pack()
        label_hidden.pack()
        username_label_widget.pack()
        self.username_entry.pack()
        label_hidden_2.pack()
        password_label_widget.pack()
        self.password_entry.pack()
        label_hidden_3.pack()
        submit_btn.pack()

    def on_submit(self, *args):
        # 回调时自动传入输入的用户名、密码、当前窗口实例,方便后续业务处理
        username = self.username_entry.get()
        password = self.password_entry.get()
        self.submit_callback(username, password, self)


# 注册窗口的提交逻辑
def register_submit(username, password, window):
    print('注册逻辑执行:', username, password)
    # 可自定义操作,比如注册成功后关闭窗口:window.destroy()

# 登录窗口的提交逻辑
def login_submit(username, password, window):
    print('登录逻辑执行:', username, password)
    # 可自定义操作,比如登录成功后关闭窗口:window.destroy()


def main():
    # 实例化注册窗口
    register_window = AuthWindow(
        title='Registration',
        img_path='registration.png',
        username_label='NEW USERNAME',
        password_label='NEW MASTER PASSWORD',
        btn_text='REGISTER',
        submit_callback=register_submit
    )
    register_window.mainloop()

    # 注册窗口关闭后实例化登录窗口
    login_window = AuthWindow(
        title='Email Manager',
        img_path='email.png',
        username_label='USERNAME',
        password_label='MASTER PASSWORD',
        btn_text='LOGIN',
        submit_callback=login_submit
    )
    login_window.mainloop()
    
if __name__ == '__main__':
    main()

#===================================icons-and-pictures-author-attribute======================================#
#===========Icons made by "https://www.freepik.com" "Freepik" from "https://www.flaticon.com/" ==============#
#===================================icons-and-pictures-author-attribute======================================#

函数封装实现(可选,适合简单场景)

如果你不想引入类,也可以用通用函数封装公共逻辑:

from tkinter import * 
import sys

def create_auth_window(title, img_path, username_label, password_label, btn_text, submit_callback):
    window = Tk()
    window.title(title)
    window.geometry('300x300')

    def on_submit(*args):
        username = login_username.get()
        password = login_password.get()
        submit_callback(username, password, window)

    label_hidden = Label(window, text="")
    # 图片绑定到窗口属性避免被垃圾回收
    window.photo = PhotoImage(file=img_path)
    photo_label = Label(window, image=window.photo)
    label_hidden_1 = Label(window, text="")
    username_label_widget = Label(window, text=username_label, font=('arial', 10, 'bold'))
    login_username = Entry(window, width=40)
    label_hidden_2 = Label(window, text="")
    password_label_widget = Label(window, text=password_label, font=('arial', 10, 'bold'))
    login_password = Entry(window, width=40, show='*')
    label_hidden_3 = Label(window, text="")

    submit_btn = Button(window, text=btn_text, width=20, height=1, font=('arial', 10, 'bold'), command=on_submit)
    login_password.bind('<Return>', on_submit)

    label_hidden_1.pack()
    photo_label.pack()
    label_hidden.pack()
    username_label_widget.pack()
    login_username.pack()
    label_hidden_2.pack()
    password_label_widget.pack()
    login_password.pack()
    label_hidden_3.pack()
    submit_btn.pack()

    return window

def register_submit(username, password, window):
    print('注册逻辑执行:', username, password)

def login_submit(username, password, window):
    print('登录逻辑执行:', username, password)

def main():
    register_window = create_auth_window(
        title='Registration',
        img_path='registration.png',
        username_label='NEW USERNAME',
        password_label='NEW MASTER PASSWORD',
        btn_text='REGISTER',
        submit_callback=register_submit
    )
    register_window.mainloop()

    login_window = create_auth_window(
        title='Email Manager',
        img_path='email.png',
        username_label='USERNAME',
        password_label='MASTER PASSWORD',
        btn_text='LOGIN',
        submit_callback=login_submit
    )
    login_window.mainloop()
    
if __name__ == '__main__':
    main()

内容的提问来源于stack exchange,提问作者lunAr- creator

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 03:15:04