【问题标题】:How to make 2 functions for 2 tkinter windows more condensed?如何使 2 个 tkinter 窗口的 2 个函数更加简洁?
【发布时间】:2021-06-24 19:46:08
【问题描述】:

问题:

我有 2 个类似的 tkinter 窗口,我想对其进行压缩或模块化(因为我有几乎 2 个完全相同的功能),这将使代码更紧凑且更易于阅读(拥有 2 个有什么意义如果我可以只有一个功能吗?)。

我将如何做到这一点,我应该使用类还是函数?

代码:

from tkinter import * 
import sys

def register_normal():
    window1=Tk()
    window1.title('Registration')
    window1.geometry('300x300')

    def register(*args):
        print('This works aswell!')


    label_hidden=Label(window1, text="")
    photo1=PhotoImage(file='registration.png')
    photo_label1=Label(window1, image=photo1)
    label_hidden_1=Label(window1,text="")
    new_username_label=Label(window1,text='NEW USERNAME',font=('arial', 10, 'bold'))
    login_username=Entry(window1, width=40)
    label_hidden_2=Label(window1,text="")
    new_password_label=Label(window1,text='NEW MASTER PASSWORD',font=('arial', 10, 'bold'))
    login_password=Entry(window1,width=40, show='*')
    label_hidden_3=Label(window1,text="")

    login_btn=Button(window1,text='REGISTER',width=20,height=1,font=('arial', 10, 'bold'), command=register)
    login_password.bind('<Return>', register)

    label_hidden_1.pack()
    photo_label1.pack()
    label_hidden.pack()
    new_username_label.pack()
    login_username.pack()
    label_hidden_2.pack()
    new_password_label.pack()
    login_password.pack()
    label_hidden_3.pack()
    login_btn.pack()

    window1.mainloop()
    
def login_normal():
    window2=Tk()
    window2.title('Email Manager')
    window2.geometry('300x300')

    def login(*args):
        print('This works!')


    label_hidden=Label(window2, text="")
    photo2=PhotoImage(file='email.png')
    photo_label2=Label(window2, image=photo2)
    label_hidden_1=Label(window2,text="")
    username_lable=Label(window2,text='USERNAME',font=('arial', 10, 'bold'))
    login_username=Entry(window2, width=40)
    label_hidden_2=Label(window2,text="")
    password_lable=Label(window2,text='MASTER PASSWORD',font=('arial', 10, 'bold'))
    login_password=Entry(window2,width=40, show='*')
    label_hidden_3=Label(window2,text="")

    login_btn=Button(window2,text='LOGIN',width=20,height=1,font=('arial', 10, 'bold'), command=login)
    login_password.bind('<Return>', login)

    label_hidden_1.pack()
    photo_label2.pack()
    label_hidden.pack()
    username_lable.pack()
    login_username.pack()
    label_hidden_2.pack()
    password_lable.pack()
    login_password.pack()
    label_hidden_3.pack()
    login_btn.pack()

    window2.mainloop()


def main():
    register_normal()
    login_normal()
    
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======================================#

【问题讨论】:

  • 一个是注册功能,一个是登录功能,两者不一样,不过如果你觉得自己在重复自己,甚至创建一个类或一个函数,然后制作这些小部件并将变量数据作为参数传递,如文本、回调、bla bla

标签: python tkinter


【解决方案1】:

我会给你一个例子,你可以使用一个模板然后编辑值,我使用的是框架,当按下不同的按钮时可以提升它。

from tkinter import *

class Form(Frame):
    def __init__(self,master,user_txt,img,pw_txt,btn_txt,callback,*args,**kwargs):
        Frame.__init__(self,master,*args,**kwargs)
        
        self.photo1 = PhotoImage(file=img)
        Label(self, image=self.photo1).pack()
        Label(self,text=user_txt,font=('arial', 10, 'bold')).pack(pady=(50,0))
        
        self.e1 = Entry(self, width=40) # self because later needs to be accessed
        self.e1.pack(pady=(0,15))
       
        Label(self,text=pw_txt,font=('arial', 10, 'bold')).pack()
        
        self.e2 = Entry(self,width=40, show='*')
        self.e2.pack(pady=(0,15))

        login_btn = Button(self,text=btn_txt,width=20,height=1,font=('arial', 10, 'bold'), command=callback)
        self.e2.bind('<Return>', lambda e: callback())
        login_btn.pack(pady=(0,50))

def log(pg, e=None): # Do your password check and other stuff
    print('Username: ', pg.e1.get())
    print('Password: ', pg.e2.get())

def reg(pg, e=None):
    print('Reg Username: ', pg.e1.get())
    print('Reg Password: ', pg.e2.get())

if __name__ == '__main__':
    root = Tk()

    register = Form(root,'NEW USERNAME',None,'NEW MASTER PASSWORD','REGISTER',lambda: reg(register))
    login    = Form(root,'USERNAME',None,'MASTER PASSWORD','LOGIN',lambda: log(login))

    Button(root,text='Switch to register page',command=lambda: register.tkraise()).grid(row=1,column=0) # To raise register frame
    Button(root,text='Switch to login page',command=lambda: login.tkraise()).grid(row=2,column=0)

    register.grid(row=0,column=0) # Place in same place so can be raised with tkraise()
    login.grid(row=0,column=0)

    root.mainloop()

我删除了空白标签并使用pady=(up,down)推动标签上下。我使用了类而不是函数,因为它是可实例化的。这个使用框架的例子也将摆脱创建更多的窗口(更现代)。

正如您所看到的,这只是一个示例,因为注册表单需要 2 个密码框(也需要确认密码),请尝试将此方法仅用于类似的概念,登录和注册是不同的功能,因此它们的表单应该看起来也不同。您只需创建一个名为Login 的类,然后从Frame 继承并将其放置在屏幕上,就像这里一样,与Registration 相同。使用此功能的一个很好的例子是用户的个人资料,所有用户的模板都是相同的,只有用户数据会有所不同,这将作为变量传递。

为了更好地理解,请阅读:

【讨论】:

  • 您好,只是一个问题:我将如何破坏其中一个窗户?说“注册”。在 reg 函数中,我放了 'pg.destory()' 但这只会删除框架而不是整个窗口。我怎么能毁掉整个窗户?谢谢:D
  • @lunAr-creator master.destroy() 会这样做,但如果它在__init__ 之外,那么您必须将其存储为self.parent = master 然后self.parent.destroy()
  • 'self.parent = master' 和 'self.parent.destory()' 是否会进入 reg 函数,因为当我运行 atm 时我得到一个“名称 master 未定义错误”?
  • @lunAr-creator 啊在这种情况下,pg.parent.destroy()
  • 这就解释了!我忘了添加它!非常感谢您的帮助:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-21
  • 2022-01-28
  • 1970-01-01
  • 1970-01-01
  • 2016-11-19
  • 2017-12-25
  • 1970-01-01
相关资源
最近更新 更多