• Python初学——窗口视窗Tkinter


    什么是 tkinter 窗口

    1.1 什么是 Tkinter

    Python自带的可编辑的GUI界面,是一个图像窗口。
    Tkinter是使用 python 进行窗口视窗设计的模块。简单的构造,多平台,多系统的兼容性, 能让它成为让你快速入门定制窗口文件的好助手。它在 python 窗口视窗模块中是一款简单型的。所以用来入门,熟悉窗口视窗的使用,非常有必要。

    tkinter 的窗口部件

    2.1 Label & Button 标签和按钮

    窗口主体框架
    每一个tkinter应用的主体框架都可以包含下面这部分,定义window窗口和window的一些属性,然后书写窗口内容,最后执行window.mainloop让窗口活起来。
    1. import tkinter as tk
    2.  
    3. window = tk.Tk()
    4. window.title('my window')
    5. window.geometry('300x100')
    6. # 这里是窗口的内容
    7. window.mainloop()
    首先建立一个用来描述的标签tk.Label(注意对象的首字母一般是大写),示例代码如下所示:
    1. l = tk.Label(window, 
    2.     text='OMG! this is TK!',    # 标签的文字
    3.     bg='green',     # 背景颜色
    4.     font=('Arial', 12),     # 字体和字体大小
    5.     width=15, height=2  # 标签长宽
    6. l.pack()    # 固定窗口位置
    运行结果如图所示:
    我们也可以通过变量的形式控制标签的显示,这时我们引入按钮 tk.Button 的概念,每点一次按钮,标签变化一次。 用以下内容替换上面的标签. 并把需要变化的文字存成变量 var:
    1. var = tk.StringVar()    # 这时文字变量储存器
    2. l = tk.Label(window, 
    3.     textvariable=var,   # 使用 textvariable 替换 text, 因为这个可以变化
    4.     bg='green', font=('Arial', 12), width=15, height=2)
    5. l.pack() 
    接着做按钮tk.Button:
    1. b = tk.Button(window, 
    2.     text='hit me',      # 显示在按钮上的文字
    3.     width=15, height=2, 
    4.     command=hit_me)     # 点击按钮式执行的命令
    5. b.pack()    # 按钮位置
    hit_me函数如下:
    1. on_hit = False  # 默认初始状态为 Falsedef hit_me():
    2.     global on_hit
    3.     if on_hit == False:     # 从 False 状态变成 True 状态
    4.         on_hit = True
    5.         var.set('you hit me')   # 设置标签的文字为 'you hit me'
    6.     else:       # 从 True 状态变成 False 状态
    7.         on_hit = False
    8.         var.set('') # 设置文字为空
    运行结果如下所示:
    没有点击动作时:
    点击第一次:
    点击第二次:
    完整代码:
    1. import tkinter as tk
    2.  
    3. window=tk.Tk()
    4. window.title('my window')
    5. window.geometry('300x100')
    6.  
    7. var=tk.StringVar()
    8. l=tk.Label(window,textvariable=var,bg='green',font=('Arial',12),width=15,
    9.            height=2)
    10. l.pack()
    11.  
    12. on_hit=False
    13. def hit_me():
    14.     global on_hit
    15.     if on_hit==False:
    16.         on_hit=True
    17.         var.set('you hit me')
    18.     else:
    19.         on_hit=False
    20.         var.set('')
    21.  
    22. b=tk.Button(window,text='hit me',width=15,
    23.             height=2,command=hit_me)
    24. b.pack()
    25.     
    26. window.mainloop()

    2.2 Entry & Text 输入, 文本框

     在定义了窗口的基础上,首先定义一个Entry,代码如下所示:
    1. e = tk.Entry(window,show=None)
    2. e.pack()
    注意这里的show,可以自定义显示你想要在Entry中显示的字符,例如像输入密码时,可令show=‘*’
    本节实现的例子功能为,如下所示的一个窗口,从上至下分别为定义的Entry、Button、Button和Text。两个Button分别命名为insert point和insert end,获取Entry中输入的内容并且分别在光标位置、末尾插入,内容显示在Text中。
    Button的定义如下所示:
    1. b1 = tk.Button(window,text='insert point',width=15,
    2.             height=2,command=insert_point)
    3. b1.pack()
    4. b2 = tk.Button(window,text='insert end',
    5.                command=insert_end)
    函数的定义如下所示:
    1. def insert_point():
    2.     var = e.get()
    3.     t.insert('insert',var)
    4. def insert_end():
    5.     var = e.get()
    6.     t.insert('end',var)
     
    完整代码如下:
    1. import tkinter as tk
    2.  
    3. window = tk.Tk()
    4. window.title('my window')
    5. window.geometry('300x300')
    6. e = tk.Entry(window,show=None)
    7. e.pack()
    8. def insert_point():
    9.     var = e.get()
    10.     t.insert('insert',var)
    11. def insert_end():
    12.     var = e.get()
    13.     t.insert('end',var)
    14. b1 = tk.Button(window,text='insert point',width=15,
    15.             height=2,command=insert_point)
    16. b1.pack()
    17. b2 = tk.Button(window,text='insert end',
    18.                command=insert_end)
    19. b2.pack()
    20. t = tk.Text(window,height=2)
    21. t.pack()
    22.  
    23. window.mainloop()
     运行结果如下所示,首先在Entry中输入111111,点击按钮1,如下:
    选择某一点作为插入位置,再在Entry中输入2,点击按钮1
    在Entry中输入3,点击按钮2
    此外,insert还能实现具体位置的内容插入,例如将inser_end函数更改如下:
    1. def insert_end():
    2.     var = e.get()
    3.     t.insert(2.2,var)
    则insert_end实现在Text的2行2列出插入内容,运行结果如下所示:

    2.3 Listbox 列表部件

    本节例子实现功能为:如下所示,从上到下分别为Label、Button和Listbox,Button实现将Listbox中当前光标选中的内容显示在Label中。
     
    在定义好窗口的基础上首先定义Label,设置底色为黄色,并且要将文本内容定义为变量,代码如下:
    1. var1=tk.StringVar()
    2. l=tk.Label(window,bg='yellow',width=4,textvariable=var1)
    3. l.pack()
    接着定义Button,命名为‘print selection’,并定义command的函数,如下所示:
    1. def print_selection():
    2.     value=lb.get(lb.curselection())
    3.     var1.set(value)
    4.     
    5. b1 = tk.Button(window, text='print selection', width=15,
    6.               height=2, command=print_selection)
    7. b1.pack()
    最后定义Listbox,如下所示实现了Listbox中内容的设置、插入、删除等。
    1. var2=tk.StringVar()
    2. var2.set((11,22,33,44))
    3. lb=tk.Listbox(window,listvariable=var2)
    4. list_items=[1,2,3,4]for item in list_items:
    5.     lb.insert('end',item)
    6. lb.insert(1,'first')
    7. lb.insert(2,'second')
    8. lb.delete(2)
    9. lb.pack()
    完整代码如下所示:
    1. import tkinter as tk
    2.  
    3. window = tk.Tk()
    4. window.title('my window')
    5. window.geometry('300x300')
    6.  
    7. var1=tk.StringVar()
    8. l=tk.Label(window,bg='yellow',width=4,textvariable=var1)
    9. l.pack()
    10. def print_selection():
    11.     value=lb.get(lb.curselection())
    12.     var1.set(value)
    13.     
    14. b1 = tk.Button(window, text='print selection', width=15,
    15.               height=2, command=print_selection)
    16. b1.pack()
    17.  
    18. var2=tk.StringVar()
    19. var2.set((11,22,33,44))
    20. lb=tk.Listbox(window,listvariable=var2)
    21. list_items=[1,2,3,4]for item in list_items:
    22.     lb.insert('end',item)
    23. lb.insert(1,'first')
    24. lb.insert(2,'second')
    25. lb.delete(2)
    26. lb.pack()
    27.  
    28. window.mainloop()

    2.4 Radiobutton 选择按钮

    如图所示,Radiobutton即为上图中可选择的按钮,本节实现选中不同的Radiobutton时打印出相应的内容。
    首先定义底色为黄色的Label,代码见完整代码。
    接着要定义三个Radiobutton:
    1. r1=tk.Radiobutton(window,text='Option A',
    2.                   variable=var,value='A',
    3.                   command=print_selection)
    4. r1.pack()
     Radiobutton放在window上,命名为‘Option A’,其中var=tk.StringVar(),接着令按钮的variable等于var,并且赋值为‘A’。
    print_selection函数的定义如下:
    1. def print_selection():
    2.     l.config(text='you have selected '+var.get())
    config能对所有的参数进行更改,在函数定义中选择text属性进行更改。
    完整代码如下:
    1. import tkinter as tk
    2.  
    3. window = tk.Tk()
    4. window.title('my window')
    5. window.geometry('300x300')
    6.  
    7. var=tk.StringVar()
    8. l=tk.Label(window,bg='yellow',width=20,text='empty')
    9. l.pack()
    10. def print_selection():
    11.     l.config(text='you have selected '+var.get())
    12.  
    13. r1=tk.Radiobutton(window,text='Option A',
    14.                   variable=var,value='A',
    15.                   command=print_selection)
    16. r1.pack()
    17. r2=tk.Radiobutton(window,text='Option B',
    18.                   variable=var,value='B',
    19.                   command=print_selection)
    20. r2.pack()
    21. r3=tk.Radiobutton(window,text='Option C',
    22.                   variable=var,value='C',
    23.                   command=print_selection)
    24. r3.pack()
    25.  
    26. window.mainloop()
    运行结果如下所示,当未选中时,Label内容显示为empty,当选中某一个Radiobutton时,则Label中显示相应的内容

    2.5 Scale 尺度

     可以被拉动的一个条,Scale返回的是一个数字。如下所示,当拉动时会在Label上显示具体的数字。
     
    完整代码如下:
    1. import tkinter as tk
    2.  
    3. window = tk.Tk()
    4. window.title('my window')
    5. window.geometry('300x300')
    6.  
    7. l=tk.Label(window,bg='yellow',width=20,text='empty')
    8. l.pack()
    9. def print_selection(v):
    10.     l.config(text='you have selected '+v)
    11.  
    12. s=tk.Scale(window,label='try me',from_=5,to=11,orient=tk.HORIZONTAL,
    13.            length=200,showvalue=0,tickinterval=3,resolution=0.01,command=print_selection)
    14. s.pack()
    15.  
    16. window.mainloop()
    定义Scale的属性时,名字为label,from to为取值范围,from_是为了区分python中的from,Scale还有横向和竖向属性,注意为tk.横向/竖向。length为显示的长度,不同于Label中的width,width的单位是字符,和length的单位是像素。showvalue即是否显示所选中的数字,取值为0时不显示,为1时显示。显示的标签单位长度为tickinterval,即显示出的数字的间隔,取值为3时,即显示5,8,11。resolution为要保留的小数个数。
    在Scale中所定义的command功能是有默认传入值的,该传入值即为Scale标签当前标注的值。所以在定义print_selection函数时需要定义一个参数用于表示该传入值。

    2.6 Checkbutton 勾选项

    与Radiobutton类似,但是Radiobutton选中一个后其他默认为不选中,但是Checkbutton类似于多选,可以选中多个。
    定义两个Checkbutton,如下所示:
    1. var1=tk.IntVar()
    2. var2=tk.IntVar()
    3. c1=tk.Checkbutton(window,text='Python',variable=var1,onvalue=1,offvalue=0,
    4.                   command=print_selection)
    5. c2=tk.Checkbutton(window,text='C++',variable=var2,onvalue=1,offvalue=0,
    6.                   command=print_selection)
    7. c1.pack()
    8. c2.pack()
    首先定义两个变量var1和var2,为整型。
    两个Checkbutton的variable分别等于var1和var,并且选中时value为1,即onvalue=1,未选中时offvalue=0.
    command的print_selection定义如下,根据var1和var2的值来进行相应的操作。
    1. def print_selection():
    2.     if(var1.get()==1)&(var2.get()==0):
    3.         l.config(text='I love only Python')
    4.     elif(var1.get()==0)&(var2.get()==1):
    5.         l.config(text='I love only C++')
    6.     elif(var1.get()==0)&(var2.get()==0):
    7.         l.config(text='I do not love either')
    8.     else:
    9.         l.config(text='I love both')
    10.         
    完整代码如下所示:
    1. import tkinter as tk
    2.  
    3. window = tk.Tk()
    4. window.title('my window')
    5. window.geometry('300x300')
    6.  
    7. l=tk.Label(window,bg='yellow',width=20,text='empty')
    8. l.pack()
    9. def print_selection():
    10.     if(var1.get()==1)&(var2.get()==0):
    11.         l.config(text='I love only Python')
    12.     elif(var1.get()==0)&(var2.get()==1):
    13.         l.config(text='I love only C++')
    14.     elif(var1.get()==0)&(var2.get()==0):
    15.         l.config(text='I do not love either')
    16.     else:
    17.         l.config(text='I love both')
    18.         
    19.     
    20. var1=tk.IntVar()
    21. var2=tk.IntVar()
    22. c1=tk.Checkbutton(window,text='Python',variable=var1,onvalue=1,offvalue=0,
    23.                   command=print_selection)
    24. c2=tk.Checkbutton(window,text='C++',variable=var2,onvalue=1,offvalue=0,
    25.                   command=print_selection)
    26. c1.pack()
    27. c2.pack()
    28.  
    29. window.mainloop()
    运行结果如下所示:
    单独选中Python时:
    单独选中C++时:
    两个都选中:
    两个都不选:

    2.7 Canvas 画布

    规定一片区域,可以放置图片、图形等等,并且可以把位置和形状进行改变。
    1. import tkinter as tk
    2.  
    3. window = tk.Tk()
    4. window.title('my window')
    5. window.geometry('300x300')
    6.  
    7. canvas=tk.Canvas(window,bg='blue',height=150,width=200)
    8. image_file=tk.PhotoImage(file='3.png')
    9. image=canvas.create_image(10,10,anchor='nw',image=image_file)
    10. x0,y0,x1,y1=90,90,120,120
    11. line=canvas.create_line(x0,y0,x1,y1)
    12. oval=canvas.create_oval(x0,y0,x1,y1,fill='yellow')
    13. arc=canvas.create_arc(x0+30,y0+30,x1+30,y1+30,start=0,extent=180,fill='green')
    14. rect=canvas.create_rectangle(100,30,100+20,30+20)
    15. canvas.pack()
    16. def moveit():
    17.     canvas.move(rect,0,2)
    18.     
    19. b=tk.Button(window,text='move',command=moveit).pack()
    20.  
    21. window.mainloop()
     首先定义一个Canvas。
    放置一张图片,首先读取读片并存入到image_file中,接着Canvas通过create.image将图片放置到画布上。注意10,10为放置的坐标,anchor意为锚点,即锚定的位置,可选择的属性如下所示:
    nw即为放置在左上角,图片最左上角的点放置的坐标应为所定义的10,10.
    接着create.line从坐标为(90,90)到(120,120)绘制一条直线。
    create.oval为绘制圆形,fill填充颜色。
    create.arc为绘制扇形,start和extent表示该扇形从0°到180°。
    create.rectangle为绘制一个正方形。
    此外,定义了一个button,该按钮的作用是每点击一次,rect对象,即为所绘制的正方形下移两格,moveit函数中0表示x方向的位移为0,2为y方向上的位移变化尺度。结果如下所示。
    单机move按钮,正方形的位置发生变化:

    2.8 Menubar 菜单

    菜单条,如下所示为本节将要完成的简单菜单条。 
     
    首先在窗口window上定义一个Menu
    1. menubar=tk.Menu(window)
    接着在menubar上创建File选项,首先同样定义一个Menu,此时的Menu是放置在menubar上的,并通过add_cascade(cascade:级联)放置在menubar上
    1. filemenu=tk.Menu(menubar,tearoff=0)
    2. menubar.add_cascade(label='File',menu=filemenu)
      接着如上图所示,在File选项中,增加New、Open、Save,分隔线、以及Exit
    1. filemenu.add_command(label='New',command=do_job)
    2. filemenu.add_command(label='Open',command=do_job)
    3. filemenu.add_command(label='Save',command=do_job)
    4. filemenu.add_separator()
    5. filemenu.add_command(label='Exit',command=window.quit)
    同理,增加Edit选项,代码详见完整代码
    接着,我们来创建File中的Submenu,如下图所示
    1. submenu=tk.Menu(filemenu)
    2. filemenu.add_cascade(label='Import',menu=submenu,underline=0)
    3. submenu.add_command(label='Submenu1',command=do_job)
     在代码中,do_job做了一个简单的显示功能,如下所示:
    1. counter=0def do_job():
    2.     global counter
    3.     l.config(text='do '+str(counter))
    4.     counter+=1
    完整代码:
    1. import tkinter as tk
    2.  
    3. window = tk.Tk()
    4. window.title('my window')
    5. window.geometry('300x300')
    6.  
    7. l=tk.Label(window,text='',bg='yellow')
    8. l.pack()
    9.  
    10. counter=0def do_job():
    11.     global counter
    12.     l.config(text='do '+str(counter))
    13.     counter+=1
    14.     
    15. menubar=tk.Menu(window)
    16. filemenu=tk.Menu(menubar,tearoff=0)
    17. menubar.add_cascade(label='File',menu=filemenu)
    18. filemenu.add_command(label='New',command=do_job)
    19. filemenu.add_command(label='Open',command=do_job)
    20. filemenu.add_command(label='Save',command=do_job)
    21. filemenu.add_separator()
    22. filemenu.add_command(label='Exit',command=window.quit)
    23.  
    24. editmenu=tk.Menu(menubar,tearoff=0)
    25. menubar.add_cascade(label='Edit',menu=editmenu)
    26. editmenu.add_command(label='Cut',command=do_job)
    27. editmenu.add_command(label='Copy',command=do_job)
    28. editmenu.add_command(label='Paste',command=do_job)
    29.  
    30. submenu=tk.Menu(filemenu)
    31. filemenu.add_cascade(label='Import',menu=submenu,underline=0)
    32. submenu.add_command(label='Submenu1',command=do_job)
    33.  
    34. window.config(menu=menubar)
    35.  
    36. window.mainloop() 

    2.9 Frame 框架

    底层框架,可以在上面放各种小部件
     
    1. import tkinter as tk
    2.  
    3. window = tk.Tk()
    4. window.title('my window')
    5. window.geometry('300x300')
    6.  
    7. tk.Label(window,text='on the window').pack()
    8.  
    9. frm=tk.Frame(window)
    10. frm.pack()
    11. frm_l=tk.Frame(frm,)
    12. frm_r=tk.Frame(frm)
    13. frm_l.pack(side='left')
    14. frm_r.pack(side='right')
    15.  
    16. tk.Label(frm_l,text='on the frm_l1').pack()
    17. tk.Label(frm_l,text='on the frm_l2').pack()
    18. tk.Label(frm_r,text='on the frm_r1').pack()
    19.  
    20. window.mainloop() 
    首先定义一个主Frame,放在window上
    接着定义了第二层的两个Frame,分别放在主Frame的左右侧
    在左边的Frame上放置了两个标签,右边放了一个标签

    2.10 messagebox 弹窗

    在window的基础上定义一个Button
    1. tk.Button(window, text='hit me', command=hit_me).pack()
    如图所示:
    接着定义一个弹窗,在运行时出现错误
    AttributeError: module 'tkinter' has no attribute 'messagebox'
    试着加入import则可运行成功
    1. from tkinter import messagebox
    messagebox有多种功能,接下来将分别细述
    (1)showinfo
    1. tk.messagebox.showinfo(title='Hi', message='hahahaha')
     (2)showwarning
    1. tk.messagebox.showwarning(title='Hi', message='nononono')
    (3)showerror
    1. tk.messagebox.showerror(title='Hi', message='No!! never')
    (4)askquestion返回是字符串,即返回的是‘yes’或者‘no’,可通过print打印出来以更好的理解
    1. print(tk.messagebox.askquestion(title='Hi', message='hahahaha'))   # return 'yes' , 'no'
    选择是打印出的值为‘yes’
    根据return的值可进一步选择需要的操作
    if return==‘yes’
    (5)askyesno
    返回的是True或者False
    1. print(tk.messagebox.askyesno(title='Hi', message='hahahaha'))   # return True, False
    同样可根据返回的值来进一步操作。
    (6)asktrycancel
    1. print(tk.messagebox.asktrycancel(title='Hi', message='hahahaha'))   # return True, False
    但是不知道为什么运行时出现错误:AttributeError: module 'tkinter.messagebox' has no attribute 'asktrycancel'
    (7)askokcancel
    1. print(tk.messagebox.askokcancel(title='Hi', message='hahahaha'))   # return True, False
    (8)askyesnocancel
    1. print(tk.messagebox.askyesnocancel(title="Hi", message="haha"))     # return, True, False, None
    完整代码:
    1. import tkinter as tk
    2.  
    3. window = tk.Tk()
    4. window.title('my window')
    5. window.geometry('200x200')
    6. def hit_me():
    7.     #tk.messagebox.showinfo(title='Hi', message='hahahaha')
    8.     #tk.messagebox.showwarning(title='Hi', message='nononono')
    9.     #tk.messagebox.showerror(title='Hi', message='No!! never')
    10.     #print(tk.messagebox.askquestion(title='Hi', message='hahahaha'))   # return 'yes' , 'no'
    11.     #print(tk.messagebox.askyesno(title='Hi', message='hahahaha'))   # return True, False
    12.     #print(tk.messagebox.asktrycancel(title='Hi', message='hahahaha'))   # return True, False
    13.     #print(tk.messagebox.askokcancel(title='Hi', message='hahahaha'))   # return True, False
    14.     print(tk.messagebox.askyesnocancel(title="Hi", message="haha"))     # return, True, False, None
    15. tk.Button(window, text='hit me', command=hit_me).pack()
    16. window.mainloop()

    2.11 pack grid place 放置位置

    (1)pack
     side属性来决定所放置的位置,共有top、bottom、left、right
    1. tk.Label(window,text='1').pack(side='top')
    2. tk.Label(window,text='1').pack(side='bottom')
    3. tk.Label(window,text='1').pack(side='left')t
    4. tk.Label(window,text='1').pack(side='right')
    (2)grid
    按照格点(方格的形式来放置)
    1. for i in range(4):
    2.     for j in range(3):
    3.         tk.Label(window,text=1).grid(row=i,column=j,padx=10,pady=10)
    无padx和pady时:
    其中padx、pady用于填充显示,padx和pady用于设置框架的外部填充显示,ipadx和ipady用于设置框架的内部显示。
    (3)place
    能精确放置到某一坐标处
    1. tk.Label(window,text=1).place(x=20,y=10,anchor='nw')

    登录窗口例子

    3.1 例子1 登录窗口

    综合前面所学习的内容,设计如下窗口
    代码如下所示:
    1. import tkinter as tk
    2.  
    3. window = tk.Tk()
    4. window.title('Welcome to Mofan Python')
    5. window.geometry('450x300')
    6. # welcome image
    7. canvas = tk.Canvas(window, height=200, width=500)
    8. image_file = tk.PhotoImage(file='welcome.gif')
    9. image = canvas.create_image(0,0, anchor='nw', image=image_file)
    10. canvas.pack(side='top')
    11. # user information
    12. tk.Label(window, text='User name: ').place(x=50, y= 150)
    13. tk.Label(window, text='Password: ').place(x=50, y= 190)
    14.  
    15. var_usr_name = tk.StringVar()
    16. var_usr_name.set('example@python.com')
    17. entry_usr_name = tk.Entry(window, textvariable=var_usr_name)
    18. entry_usr_name.place(x=160, y=150)
    19. var_usr_pwd = tk.StringVar()
    20. entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, show='*')
    21. entry_usr_pwd.place(x=160, y=190)
    22. def usr_login():
    23.     passdef usr_sign_up():
    24.     pass
    25. # login and sign up button
    26. btn_login = tk.Button(window, text='Login', command=usr_login)
    27. btn_login.place(x=170, y=230)
    28. btn_sign_up = tk.Button(window, text='Sign up', command=usr_sign_up)
    29. btn_sign_up.place(x=270, y=230)
    30.  
    31. window.mainloop()

    3.2 例子1 登录窗口

     本节添加了Login的功能,代码如下:
    1. def usr_login():
    2.     usr_name = var_usr_name.get()
    3.     usr_pwd = var_usr_pwd.get()
    4.     try:
    5.         with open('usrs_info.pickle', 'rb') as usr_file:
    6.             usrs_info = pickle.load(usr_file)
    7.     except FileNotFoundError:
    8.         with open('usrs_info.pickle', 'wb') as usr_file:
    9.             usrs_info = {'admin': 'admin'}
    10.             pickle.dump(usrs_info, usr_file)
    11.     if usr_name in usrs_info:
    12.         if usr_pwd == usrs_info[usr_name]:
    13.             tk.messagebox.showinfo(title='Welcome', message='How are you? ' + usr_name)
    14.         else:
    15.             tk.messagebox.showerror(message='Error, your password is wrong, try again.')
    16.     else:
    17.         is_sign_up = tk.messagebox.askyesno('Welcome',
    18.                                'You have not sign up yet. Sign up today?')
    19.         if is_sign_up:
    20.             usr_sign_up()
     
    首先以读二进制的方式打开并下载存储用户信息的文件,如果文件不存在,则建立该文件,并且加入了用户名为admin、密码为admin的用户。
    如果用户名在用户信息文件中存在,密码输入正确时,会弹出欢迎窗口,否则则显示密码错误。
    如果用户不存在,则弹出窗口询问是否要进行注册,并通过返回的True或是False的值进行注册操作。
    运行结果如下所示:
    输入密码错误时:
    正确输入密码时:
    用户不存在时:

    3.3 例子1 登录窗口

     注册时将会弹出新窗口,如下所示:
    首先定义一个新窗口
    1. window_sign_up=tk.Toplevel(window)
    2. window_sign_up.geometry('350x200')
    3. window_sign_up.title('Sign up window')
    定义User name、Password和Confirm password,以及三个Entry和一个Button
    1. new_name = tk.StringVar()
    2. new_name.set('example@python.com')
    3. tk.Label(window_sign_up, text='User name: ').place(x=10, y= 10)
    4. entry_new_name = tk.Entry(window_sign_up, textvariable=new_name)
    5. entry_new_name.place(x=150, y=10)
    6.  
    7. new_pwd = tk.StringVar()
    8. tk.Label(window_sign_up, text='Password: ').place(x=10, y=50)
    9. entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show='*')
    10. entry_usr_pwd.place(x=150, y=50)
    11.  
    12. new_pwd_confirm = tk.StringVar()
    13. tk.Label(window_sign_up, text='Confirm password: ').place(x=10, y= 90)
    14. entry_usr_pwd_confirm = tk.Entry(window_sign_up, textvariable=new_pwd_confirm, show='*')
    15. entry_usr_pwd_confirm.place(x=150, y=90)
    16.  
    17. btn_confirm_sign_up = tk.Button(window_sign_up, text='Sign up', command=sign_to_Mofan_Python)
    18. btn_confirm_sign_up.place(x=150, y=130)
     
    接着定义函数sign_to_Mofan_Python
    1.  def sign_to_Mofan_Python():
    2.         np = new_pwd.get()
    3.         npf = new_pwd_confirm.get()
    4.         nn = new_name.get()
    5.         with open('usrs_info.pickle', 'rb') as usr_file:
    6.             exist_usr_info = pickle.load(usr_file)
    7.         if np != npf:
    8.             tk.messagebox.showerror('Error', 'Password and confirm password must be the same!')
    9.         elif nn in exist_usr_info:
    10.             tk.messagebox.showerror('Error', 'The user has already signed up!')
    11.         else:
    12.             exist_usr_info[nn] = np
    13.             with open('usrs_info.pickle', 'wb') as usr_file:
    14.                 pickle.dump(exist_usr_info, usr_file)
    15.             tk.messagebox.showinfo('Welcome', 'You have successfully signed up!')
    16.             window_sign_up.destroy()
     
    打开读取文件usrs_info,首先判断密码是否相等,如果不相等,则弹出窗口提示密码输入不一致
    如果用户名存在,则弹出窗口提示用户名已经注册
    注册合格的话,则将信息存放,pickle里面存放的是一个字典,exist_usr_info[nn] = np该句即为username:password,通过dump将新的注册信息传入到用户信息文件中。并弹出窗口提示注册成功
    最后通过destory关闭注册窗口
    完整代码如下:
    1. def usr_sign_up():
    2.     def sign_to_Mofan_Python():
    3.         np = new_pwd.get()
    4.         npf = new_pwd_confirm.get()
    5.         nn = new_name.get()
    6.         with open('usrs_info.pickle', 'rb') as usr_file:
    7.             exist_usr_info = pickle.load(usr_file)
    8.         if np != npf:
    9.             tk.messagebox.showerror('Error', 'Password and confirm password must be the same!')
    10.         elif nn in exist_usr_info:
    11.             tk.messagebox.showerror('Error', 'The user has already signed up!')
    12.         else:
    13.             exist_usr_info[nn] = np
    14.             with open('usrs_info.pickle', 'wb') as usr_file:
    15.                 pickle.dump(exist_usr_info, usr_file)
    16.             tk.messagebox.showinfo('Welcome', 'You have successfully signed up!')
    17.             window_sign_up.destroy()
    18.             
    19.     window_sign_up=tk.Toplevel(window)
    20.     window_sign_up.geometry('350x200')
    21.     window_sign_up.title('Sign up window')
    22.  
    23.     new_name = tk.StringVar()
    24.     new_name.set('example@python.com')
    25.     tk.Label(window_sign_up, text='User name: ').place(x=10, y=10)
    26.     entry_new_name = tk.Entry(window_sign_up, textvariable=new_name)
    27.     entry_new_name.place(x=150, y=10)
    28.  
    29.     new_pwd = tk.StringVar()
    30.     tk.Label(window_sign_up, text='Password: ').place(x=10, y=50)
    31.     entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show='*')
    32.     entry_usr_pwd.place(x=150, y=50)
    33.  
    34.     new_pwd_confirm = tk.StringVar()
    35.     tk.Label(window_sign_up, text='Confirm password: ').place(x=10, y= 90)
    36.     entry_usr_pwd_confirm = tk.Entry(window_sign_up, textvariable=new_pwd_confirm, show='*')
    37.     entry_usr_pwd_confirm.place(x=150, y=90)
    38.  
    39.     btn_confirm_sign_up = tk.Button(window_sign_up, text='Sign up', command=sign_to_Mofan_Python)
    40.     btn_confirm_sign_up.place(x=150, y=130)
     运行结果如下所示:
    当用户名已存在时:
    当密码输入不一致时:
     当注册成功时:
    点击确定后注册窗口关闭
    用注册的用户进行登录,弹出窗口:
     

  • 相关阅读:
    [NLP] 语义网络与知识图谱入门(二)
    [NLP] 语义网络与知识图谱入门(一)
    [论文理解] LFFD: A Light and Fast Face Detector for Edge Devices
    [学习笔记] 匈牙利匹配
    [NLP] nlp-lstm-cos -> sin
    [ros] ros入门记录
    [推荐系统] 两种协同过滤
    [NN] Guided Backpropgation 可视化
    [torch] pytorch hook学习
    python高级编程和算法
  • 原文地址:https://www.cnblogs.com/Javauser/p/8951824.html
Copyright © 2020-2023  润新知