1. 程式人生 > >Python Tkinter學習(三)

Python Tkinter學習(三)

extent list ide 分享圖片 destroy 字符串 log point 值範圍

Python初學——窗口視窗Tkinter

1.1 什麽是 Tkinter

Python自帶的可編輯的GUI界面,是一個圖像窗口。

Tkinter是使用 python 進行窗口視窗設計的模塊。簡單的構造,多平臺,多系統的兼容性, 能讓它成為讓你快速入門定制窗口文件的好助手。它在 python 窗口視窗模塊中是一款簡單型的。所以用來入門,熟悉窗口視窗的使用,非常有必要。

tkinter 的窗口部件

2.1 Label & Button 標簽和按鈕

窗口主體框架

每一個tkinter應用的主體框架都可以包含下面這部分,定義window窗口和window的一些屬性,然後書寫窗口內容,最後執行window.mainloop讓窗口活起來。

技術分享圖片
import tkinter as tk

window = tk.Tk()
window.title(‘my window‘)
window.geometry(‘300x100‘)

# 這裏是窗口的內容

window.mainloop()
技術分享圖片

首先建立一個用來描述的標簽tk.Label(註意對象的首字母一般是大寫),示例代碼如下所示:

技術分享圖片
l = tk.Label(window, 
    text=‘OMG! this is TK!‘,    # 標簽的文字
    bg=‘green‘,     # 背景顏色
    font=(‘Arial‘, 12),     # 字體和字體大小
    width=15, height=2)  # 標簽長寬
l.pack()    # 固定窗口位置
技術分享圖片

運行結果如圖所示:

技術分享圖片

我們也可以通過變量的形式控制標簽的顯示,這時我們引入按鈕 tk.Button 的概念,每點一次按鈕,標簽變化一次。 用以下內容替換上面的標簽. 並把需要變化的文字存成變量 var:

var = tk.StringVar()    # 這時文字變量儲存器
l = tk.Label(window, 
    textvariable=var,   # 使用 textvariable 替換 text, 因為這個可以變化
    bg=‘green‘, font=(‘Arial‘, 12), width=15, height=2)
l.pack() 

接著做按鈕tk.Button:

b = tk.Button(window, 
    text=‘hit me‘,      # 顯示在按鈕上的文字
    width=15, height=2, 
    command=hit_me)     # 點擊按鈕式執行的命令
b.pack()    # 按鈕位置

hit_me函數如下:

技術分享圖片
on_hit = False  # 默認初始狀態為 False
def hit_me():
    global on_hit
    if on_hit == False:     # 從 False 狀態變成 True 狀態
        on_hit = True
        var.set(‘you hit me‘)   # 設置標簽的文字為 ‘you hit me‘
    else:       # 從 True 狀態變成 False 狀態
        on_hit = False
        var.set(‘‘) # 設置文字為空
技術分享圖片

運行結果如下所示:

沒有點擊動作時:

技術分享圖片

點擊第一次:

技術分享圖片

點擊第二次:

技術分享圖片

完整代碼:

技術分享圖片
import tkinter as tk

window=tk.Tk()
window.title(‘my window‘)
window.geometry(‘300x100‘)

var=tk.StringVar()
l=tk.Label(window,textvariable=var,bg=‘green‘,font=(‘Arial‘,12),width=15,
           height=2)
l.pack()

on_hit=False

def hit_me():
    global on_hit
    if on_hit==False:
        on_hit=True
        var.set(‘you hit me‘)
    else:
        on_hit=False
        var.set(‘‘)

b=tk.Button(window,text=‘hit me‘,width=15,
            height=2,command=hit_me)
b.pack()
    
window.mainloop()
技術分享圖片

2.2 Entry & Text 輸入, 文本框

在定義了窗口的基礎上,首先定義一個Entry,代碼如下所示:

e = tk.Entry(window,show=None)
e.pack()

註意這裏的show,可以自定義顯示你想要在Entry中顯示的字符,例如像輸入密碼時,可令show=‘*’

本節實現的例子功能為,如下所示的一個窗口,從上至下分別為定義的Entry、Button、Button和Text。兩個Button分別命名為insert point和insert end,獲取Entry中輸入的內容並且分別在光標位置、末尾插入,內容顯示在Text中。

技術分享圖片

Button的定義如下所示:

b1 = tk.Button(window,text=‘insert point‘,width=15,
            height=2,command=insert_point)
b1.pack()
b2 = tk.Button(window,text=‘insert end‘,
               command=insert_end)

函數的定義如下所示:

技術分享圖片
def insert_point():
    var = e.get()
    t.insert(‘insert‘,var)

def insert_end():
    var = e.get()
    t.insert(‘end‘,var)
技術分享圖片


完整代碼如下:

技術分享圖片
import tkinter as tk

window = tk.Tk()
window.title(‘my window‘)
window.geometry(‘300x300‘)
e = tk.Entry(window,show=None)
e.pack()

def insert_point():
    var = e.get()
    t.insert(‘insert‘,var)

def insert_end():
    var = e.get()
    t.insert(‘end‘,var)
b1 = tk.Button(window,text=‘insert point‘,width=15,
            height=2,command=insert_point)
b1.pack()
b2 = tk.Button(window,text=‘insert end‘,
               command=insert_end)
b2.pack()
t = tk.Text(window,height=2)
t.pack()

window.mainloop()
技術分享圖片

運行結果如下所示,首先在Entry中輸入111111,點擊按鈕1,如下:

技術分享圖片

選擇某一點作為插入位置,再在Entry中輸入2,點擊按鈕1

技術分享圖片

在Entry中輸入3,點擊按鈕2

技術分享圖片

此外,insert還能實現具體位置的內容插入,例如將inser_end函數更改如下:

def insert_end():
    var = e.get()
    t.insert(2.2,var)

則insert_end實現在Text的2行2列出插入內容,運行結果如下所示:

技術分享圖片

2.3 Listbox 列表部件

本節例子實現功能為:如下所示,從上到下分別為Label、Button和Listbox,Button實現將Listbox中當前光標選中的內容顯示在Label中。

技術分享圖片

在定義好窗口的基礎上首先定義Label,設置底色為黃色,並且要將文本內容定義為變量,代碼如下:

var1=tk.StringVar()
l=tk.Label(window,bg=‘yellow‘,width=4,textvariable=var1)
l.pack()

接著定義Button,命名為‘print selection’,並定義command的函數,如下所示:

技術分享圖片
def print_selection():
    value=lb.get(lb.curselection())
    var1.set(value)
    
b1 = tk.Button(window, text=‘print selection‘, width=15,
              height=2, command=print_selection)
b1.pack()
技術分享圖片

最後定義Listbox,如下所示實現了Listbox中內容的設置、插入、刪除等。

技術分享圖片
var2=tk.StringVar()
var2.set((11,22,33,44))
lb=tk.Listbox(window,listvariable=var2)
list_items=[1,2,3,4]
for item in list_items:
    lb.insert(‘end‘,item)
lb.insert(1,‘first‘)
lb.insert(2,‘second‘)
lb.delete(2)
lb.pack()
技術分享圖片

完整代碼如下所示:

技術分享圖片
import tkinter as tk

window = tk.Tk()
window.title(‘my window‘)
window.geometry(‘300x300‘)

var1=tk.StringVar()
l=tk.Label(window,bg=‘yellow‘,width=4,textvariable=var1)
l.pack()

def print_selection():
    value=lb.get(lb.curselection())
    var1.set(value)
    
b1 = tk.Button(window, text=‘print selection‘, width=15,
              height=2, command=print_selection)
b1.pack()

var2=tk.StringVar()
var2.set((11,22,33,44))
lb=tk.Listbox(window,listvariable=var2)
list_items=[1,2,3,4]
for item in list_items:
    lb.insert(‘end‘,item)
lb.insert(1,‘first‘)
lb.insert(2,‘second‘)
lb.delete(2)
lb.pack()

window.mainloop()
技術分享圖片

2.4 Radiobutton 選擇按鈕

技術分享圖片

如圖所示,Radiobutton即為上圖中可選擇的按鈕,本節實現選中不同的Radiobutton時打印出相應的內容。

首先定義底色為黃色的Label,代碼見完整代碼。

接著要定義三個Radiobutton:

r1=tk.Radiobutton(window,text=‘Option A‘,
                  variable=var,value=‘A‘,
                  command=print_selection)
r1.pack()

Radiobutton放在window上,命名為‘Option A’,其中var=tk.StringVar(),接著令按鈕的variable等於var,並且賦值為‘A’。

print_selection函數的定義如下:

def print_selection():
    l.config(text=‘you have selected ‘+var.get())

config能對所有的參數進行更改,在函數定義中選擇text屬性進行更改。

完整代碼如下:

技術分享圖片
import tkinter as tk

window = tk.Tk()
window.title(‘my window‘)
window.geometry(‘300x300‘)

var=tk.StringVar()
l=tk.Label(window,bg=‘yellow‘,width=20,text=‘empty‘)
l.pack()

def print_selection():
    l.config(text=‘you have selected ‘+var.get())

r1=tk.Radiobutton(window,text=‘Option A‘,
                  variable=var,value=‘A‘,
                  command=print_selection)
r1.pack()
r2=tk.Radiobutton(window,text=‘Option B‘,
                  variable=var,value=‘B‘,
                  command=print_selection)
r2.pack()
r3=tk.Radiobutton(window,text=‘Option C‘,
                  variable=var,value=‘C‘,
                  command=print_selection)
r3.pack()

window.mainloop()
技術分享圖片

運行結果如下所示,當未選中時,Label內容顯示為empty,當選中某一個Radiobutton時,則Label中顯示相應的內容

技術分享圖片

2.5 Scale 尺度

可以被拉動的一個條,Scale返回的是一個數字。如下所示,當拉動時會在Label上顯示具體的數字。

技術分享圖片

完整代碼如下:

技術分享圖片
import tkinter as tk

window = tk.Tk()
window.title(‘my window‘)
window.geometry(‘300x300‘)

l=tk.Label(window,bg=‘yellow‘,width=20,text=‘empty‘)
l.pack()

def print_selection(v):
    l.config(text=‘you have selected ‘+v)

s=tk.Scale(window,label=‘try me‘,from_=5,to=11,orient=tk.HORIZONTAL,
           length=200,showvalue=0,tickinterval=3,resolution=0.01,command=print_selection)
s.pack()

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,如下所示:

技術分享圖片
var1=tk.IntVar()
var2=tk.IntVar()
c1=tk.Checkbutton(window,text=‘Python‘,variable=var1,onvalue=1,offvalue=0,
                  command=print_selection)
c2=tk.Checkbutton(window,text=‘C++‘,variable=var2,onvalue=1,offvalue=0,
                  command=print_selection)
c1.pack()
c2.pack()
技術分享圖片

首先定義兩個變量var1和var2,為整型。

兩個Checkbutton的variable分別等於var1和var,並且選中時value為1,即onvalue=1,未選中時offvalue=0.

command的print_selection定義如下,根據var1和var2的值來進行相應的操作。

技術分享圖片
def print_selection():
    if(var1.get()==1)&(var2.get()==0):
        l.config(text=‘I love only Python‘)
    elif(var1.get()==0)&(var2.get()==1):
        l.config(text=‘I love only C++‘)
    elif(var1.get()==0)&(var2.get()==0):
        l.config(text=‘I do not love either‘)
    else:
        l.config(text=‘I love both‘)
        
技術分享圖片

完整代碼如下所示:

技術分享圖片
import tkinter as tk

window = tk.Tk()
window.title(‘my window‘)
window.geometry(‘300x300‘)

l=tk.Label(window,bg=‘yellow‘,width=20,text=‘empty‘)
l.pack()

def print_selection():
    if(var1.get()==1)&(var2.get()==0):
        l.config(text=‘I love only Python‘)
    elif(var1.get()==0)&(var2.get()==1):
        l.config(text=‘I love only C++‘)
    elif(var1.get()==0)&(var2.get()==0):
        l.config(text=‘I do not love either‘)
    else:
        l.config(text=‘I love both‘)
        
    
var1=tk.IntVar()
var2=tk.IntVar()
c1=tk.Checkbutton(window,text=‘Python‘,variable=var1,onvalue=1,offvalue=0,
                  command=print_selection)
c2=tk.Checkbutton(window,text=‘C++‘,variable=var2,onvalue=1,offvalue=0,
                  command=print_selection)
c1.pack()
c2.pack()

window.mainloop()
技術分享圖片

運行結果如下所示:

技術分享圖片

單獨選中Python時:

技術分享圖片

單獨選中C++時:
技術分享圖片

兩個都選中:
技術分享圖片

兩個都不選:
技術分享圖片

2.7 Canvas 畫布

規定一片區域,可以放置圖片、圖形等等,並且可以把位置和形狀進行改變。

技術分享圖片
import tkinter as tk

window = tk.Tk()
window.title(‘my window‘)
window.geometry(‘300x300‘)

canvas=tk.Canvas(window,bg=‘blue‘,height=150,width=200)
image_file=tk.PhotoImage(file=‘3.png‘)
image=canvas.create_image(10,10,anchor=‘nw‘,image=image_file)
x0,y0,x1,y1=90,90,120,120
line=canvas.create_line(x0,y0,x1,y1)
oval=canvas.create_oval(x0,y0,x1,y1,fill=‘yellow‘)
arc=canvas.create_arc(x0+30,y0+30,x1+30,y1+30,start=0,extent=180,fill=‘green‘)
rect=canvas.create_rectangle(100,30,100+20,30+20)
canvas.pack()

def moveit():
    canvas.move(rect,0,2)
    
b=tk.Button(window,text=‘move‘,command=moveit).pack()

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

menubar=tk.Menu(window)

接著在menubar上創建File選項,首先同樣定義一個Menu,此時的Menu是放置在menubar上的,並通過add_cascade(cascade:級聯)放置在menubar上

filemenu=tk.Menu(menubar,tearoff=0)
menubar.add_cascade(label=‘File‘,menu=filemenu)

接著如上圖所示,在File選項中,增加New、Open、Save,分隔線、以及Exit

filemenu.add_command(label=‘New‘,command=do_job)
filemenu.add_command(label=‘Open‘,command=do_job)
filemenu.add_command(label=‘Save‘,command=do_job)
filemenu.add_separator()
filemenu.add_command(label=‘Exit‘,command=window.quit)

同理,增加Edit選項,代碼詳見完整代碼

技術分享圖片

接著,我們來創建File中的Submenu,如下圖所示

技術分享圖片

submenu=tk.Menu(filemenu)
filemenu.add_cascade(label=‘Import‘,menu=submenu,underline=0)
submenu.add_command(label=‘Submenu1‘,command=do_job)

在代碼中,do_job做了一個簡單的顯示功能,如下所示:

counter=0
def do_job():
    global counter
    l.config(text=‘do ‘+str(counter))
    counter+=1

完整代碼:

技術分享圖片
import tkinter as tk

window = tk.Tk()
window.title(‘my window‘)
window.geometry(‘300x300‘)

l=tk.Label(window,text=‘‘,bg=‘yellow‘)
l.pack()

counter=0
def do_job():
    global counter
    l.config(text=‘do ‘+str(counter))
    counter+=1
    
menubar=tk.Menu(window)
filemenu=tk.Menu(menubar,tearoff=0)
menubar.add_cascade(label=‘File‘,menu=filemenu)
filemenu.add_command(label=‘New‘,command=do_job)
filemenu.add_command(label=‘Open‘,command=do_job)
filemenu.add_command(label=‘Save‘,command=do_job)
filemenu.add_separator()
filemenu.add_command(label=‘Exit‘,command=window.quit)

editmenu=tk.Menu(menubar,tearoff=0)
menubar.add_cascade(label=‘Edit‘,menu=editmenu)
editmenu.add_command(label=‘Cut‘,command=do_job)
editmenu.add_command(label=‘Copy‘,command=do_job)
editmenu.add_command(label=‘Paste‘,command=do_job)

submenu=tk.Menu(filemenu)
filemenu.add_cascade(label=‘Import‘,menu=submenu,underline=0)
submenu.add_command(label=‘Submenu1‘,command=do_job)

window.config(menu=menubar)

window.mainloop() 
技術分享圖片

2.9 Frame 框架

底層框架,可以在上面放各種小部件

技術分享圖片

技術分享圖片
import tkinter as tk

window = tk.Tk()
window.title(‘my window‘)
window.geometry(‘300x300‘)

tk.Label(window,text=‘on the window‘).pack()

frm=tk.Frame(window)
frm.pack()
frm_l=tk.Frame(frm,)
frm_r=tk.Frame(frm)
frm_l.pack(side=‘left‘)
frm_r.pack(side=‘right‘)

tk.Label(frm_l,text=‘on the frm_l1‘).pack()
tk.Label(frm_l,text=‘on the frm_l2‘).pack()
tk.Label(frm_r,text=‘on the frm_r1‘).pack()

window.mainloop() 
技術分享圖片

首先定義一個主Frame,放在window上

接著定義了第二層的兩個Frame,分別放在主Frame的左右側

在左邊的Frame上放置了兩個標簽,右邊放了一個標簽

2.10 messagebox 彈窗

在window的基礎上定義一個Button

tk.Button(window, text=‘hit me‘, command=hit_me).pack()

如圖所示:

技術分享圖片

接著定義一個彈窗,在運行時出現錯誤

AttributeError: module ‘tkinter‘ has no attribute ‘messagebox‘

試著加入import則可運行成功

from tkinter import messagebox

messagebox有多種功能,接下來將分別細述

(1)showinfo

tk.messagebox.showinfo(title=‘Hi‘, message=‘hahahaha‘)

技術分享圖片

(2)showwarning

tk.messagebox.showwarning(title=‘Hi‘, message=‘nononono‘)

技術分享圖片

(3)showerror

tk.messagebox.showerror(title=‘Hi‘, message=‘No!! never‘)

技術分享圖片

(4)askquestion返回是字符串,即返回的是‘yes’或者‘no’,可通過print打印出來以更好的理解

print(tk.messagebox.askquestion(title=‘Hi‘, message=‘hahahaha‘))   # return ‘yes‘ , ‘no‘

技術分享圖片

選擇是打印出的值為‘yes’

技術分享圖片

根據return的值可進一步選擇需要的操作

if return==‘yes’

(5)askyesno

返回的是True或者False

print(tk.messagebox.askyesno(title=‘Hi‘, message=‘hahahaha‘))   # return True, False

技術分享圖片

同樣可根據返回的值來進一步操作。

(6)asktrycancel

print(tk.messagebox.asktrycancel(title=‘Hi‘, message=‘hahahaha‘))   # return True, False

但是不知道為什麽運行時出現錯誤:AttributeError: module ‘tkinter.messagebox‘ has no attribute ‘asktrycancel‘

(7)askokcancel

print(tk.messagebox.askokcancel(title=‘Hi‘, message=‘hahahaha‘))   # return True, False

技術分享圖片

(8)askyesnocancel

print(tk.messagebox.askyesnocancel(title="Hi", message="haha"))     # return, True, False, None

技術分享圖片

完整代碼:

技術分享圖片
import tkinter as tk

window = tk.Tk()
window.title(‘my window‘)
window.geometry(‘200x200‘)

def hit_me():
    #tk.messagebox.showinfo(title=‘Hi‘, message=‘hahahaha‘)
    #tk.messagebox.showwarning(title=‘Hi‘, message=‘nononono‘)
    #tk.messagebox.showerror(title=‘Hi‘, message=‘No!! never‘)
    #print(tk.messagebox.askquestion(title=‘Hi‘, message=‘hahahaha‘))   # return ‘yes‘ , ‘no‘
    #print(tk.messagebox.askyesno(title=‘Hi‘, message=‘hahahaha‘))   # return True, False
    #print(tk.messagebox.asktrycancel(title=‘Hi‘, message=‘hahahaha‘))   # return True, False
    #print(tk.messagebox.askokcancel(title=‘Hi‘, message=‘hahahaha‘))   # return True, False
    print(tk.messagebox.askyesnocancel(title="Hi", message="haha"))     # return, True, False, None

tk.Button(window, text=‘hit me‘, command=hit_me).pack()
window.mainloop()
技術分享圖片

2.11 pack grid place 放置位置

(1)pack

side屬性來決定所放置的位置,共有top、bottom、left、right

tk.Label(window,text=‘1‘).pack(side=‘top‘)
tk.Label(window,text=‘1‘).pack(side=‘bottom‘)
tk.Label(window,text=‘1‘).pack(side=‘left‘)t
tk.Label(window,text=‘1‘).pack(side=‘right‘)

技術分享圖片

(2)grid

按照格點(方格的形式來放置)

for i in range(4):
    for j in range(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

能精確放置到某一坐標處

tk.Label(window,text=1).place(x=20,y=10,anchor=‘nw‘)

技術分享圖片

登錄窗口例子

3.1 例子1 登錄窗口

綜合前面所學習的內容,設計如下窗口

技術分享圖片

代碼如下所示:

技術分享圖片
import tkinter as tk

window = tk.Tk()
window.title(‘Welcome to Mofan Python‘)
window.geometry(‘450x300‘)

# welcome image
canvas = tk.Canvas(window, height=200, width=500)
image_file = tk.PhotoImage(file=‘welcome.gif‘)
image = canvas.create_image(0,0, anchor=‘nw‘, image=image_file)
canvas.pack(side=‘top‘)

# user information
tk.Label(window, text=‘User name: ‘).place(x=50, y= 150)
tk.Label(window, text=‘Password: ‘).place(x=50, y= 190)

var_usr_name = tk.StringVar()
var_usr_name.set(‘[email protected]‘)
entry_usr_name = tk.Entry(window, textvariable=var_usr_name)
entry_usr_name.place(x=160, y=150)
var_usr_pwd = tk.StringVar()
entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, show=‘*‘)
entry_usr_pwd.place(x=160, y=190)

def usr_login():
    pass
def usr_sign_up():
    pass

# login and sign up button
btn_login = tk.Button(window, text=‘Login‘, command=usr_login)
btn_login.place(x=170, y=230)
btn_sign_up = tk.Button(window, text=‘Sign up‘, command=usr_sign_up)
btn_sign_up.place(x=270, y=230)

window.mainloop()
技術分享圖片

3.2 例子1 登錄窗口

本節添加了Login的功能,代碼如下:

技術分享圖片
def usr_login():
    usr_name = var_usr_name.get()
    usr_pwd = var_usr_pwd.get()
    try:
        with open(‘usrs_info.pickle‘, ‘rb‘) as usr_file:
            usrs_info = pickle.load(usr_file)
    except FileNotFoundError:
        with open(‘usrs_info.pickle‘, ‘wb‘) as usr_file:
            usrs_info = {‘admin‘: ‘admin‘}
            pickle.dump(usrs_info, usr_file)
    if usr_name in usrs_info:
        if usr_pwd == usrs_info[usr_name]:
            tk.messagebox.showinfo(title=‘Welcome‘, message=‘How are you? ‘ + usr_name)
        else:
            tk.messagebox.showerror(message=‘Error, your password is wrong, try again.‘)
    else:
        is_sign_up = tk.messagebox.askyesno(‘Welcome‘,
                               ‘You have not sign up yet. Sign up today?‘)
        if is_sign_up:
            usr_sign_up()
技術分享圖片

首先以讀二進制的方式打開並下載存儲用戶信息的文件,如果文件不存在,則建立該文件,並且加入了用戶名為admin、密碼為admin的用戶。

如果用戶名在用戶信息文件中存在,密碼輸入正確時,會彈出歡迎窗口,否則則顯示密碼錯誤。

如果用戶不存在,則彈出窗口詢問是否要進行註冊,並通過返回的True或是False的值進行註冊操作。

運行結果如下所示:
輸入密碼錯誤時:

技術分享圖片

正確輸入密碼時:
技術分享圖片

用戶不存在時:
技術分享圖片

3.3 例子1 登錄窗口

註冊時將會彈出新窗口,如下所示:

技術分享圖片

首先定義一個新窗口

window_sign_up=tk.Toplevel(window)
window_sign_up.geometry(‘350x200‘)
window_sign_up.title(‘Sign up window‘)

定義User name、Password和Confirm password,以及三個Entry和一個Button

技術分享圖片
new_name = tk.StringVar()
new_name.set(‘[email protected]‘)
tk.Label(window_sign_up, text=‘User name: ‘).place(x=10, y= 10)
entry_new_name = tk.Entry(window_sign_up, textvariable=new_name)
entry_new_name.place(x=150, y=10)

new_pwd = tk.StringVar()
tk.Label(window_sign_up, text=‘Password: ‘).place(x=10, y=50)
entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show=‘*‘)
entry_usr_pwd.place(x=150, y=50)

new_pwd_confirm = tk.StringVar()
tk.Label(window_sign_up, text=‘Confirm password: ‘).place(x=10, y= 90)
entry_usr_pwd_confirm = tk.Entry(window_sign_up, textvariable=new_pwd_confirm, show=‘*‘)
entry_usr_pwd_confirm.place(x=150, y=90)

btn_confirm_sign_up = tk.Button(window_sign_up, text=‘Sign up‘, command=sign_to_Mofan_Python)
btn_confirm_sign_up.place(x=150, y=130)
技術分享圖片

接著定義函數sign_to_Mofan_Python

技術分享圖片
 def sign_to_Mofan_Python():
        np = new_pwd.get()
        npf = new_pwd_confirm.get()
        nn = new_name.get()
        with open(‘usrs_info.pickle‘, ‘rb‘) as usr_file:
            exist_usr_info = pickle.load(usr_file)
        if np != npf:
            tk.messagebox.showerror(‘Error‘, ‘Password and confirm password must be the same!‘)
        elif nn in exist_usr_info:
            tk.messagebox.showerror(‘Error‘, ‘The user has already signed up!‘)
        else:
            exist_usr_info[nn] = np
            with open(‘usrs_info.pickle‘, ‘wb‘) as usr_file:
                pickle.dump(exist_usr_info, usr_file)
            tk.messagebox.showinfo(‘Welcome‘, ‘You have successfully signed up!‘)
            window_sign_up.destroy()
技術分享圖片

打開讀取文件usrs_info,首先判斷密碼是否相等,如果不相等,則彈出窗口提示密碼輸入不一致

如果用戶名存在,則彈出窗口提示用戶名已經註冊

註冊合格的話,則將信息存放,pickle裏面存放的是一個字典,exist_usr_info[nn] = np該句即為username:password,通過dump將新的註冊信息傳入到用戶信息文件中。並彈出窗口提示註冊成功

最後通過destory關閉註冊窗口

完整代碼如下:

技術分享圖片
def usr_sign_up():
    def sign_to_Mofan_Python():
        np = new_pwd.get()
        npf = new_pwd_confirm.get()
        nn = new_name.get()
        with open(‘usrs_info.pickle‘, ‘rb‘) as usr_file:
            exist_usr_info = pickle.load(usr_file)
        if np != npf:
            tk.messagebox.showerror(‘Error‘, ‘Password and confirm password must be the same!‘)
        elif nn in exist_usr_info:
            tk.messagebox.showerror(‘Error‘, ‘The user has already signed up!‘)
        else:
            exist_usr_info[nn] = np
            with open(‘usrs_info.pickle‘, ‘wb‘) as usr_file:
                pickle.dump(exist_usr_info, usr_file)
            tk.messagebox.showinfo(‘Welcome‘, ‘You have successfully signed up!‘)
            window_sign_up.destroy()
            
    window_sign_up=tk.Toplevel(window)
    window_sign_up.geometry(‘350x200‘)
    window_sign_up.title(‘Sign up window‘)

    new_name = tk.StringVar()
    new_name.set(‘[email protected]‘)
    tk.Label(window_sign_up, text=‘User name: ‘).place(x=10, y=10)
    entry_new_name = tk.Entry(window_sign_up, textvariable=new_name)
    entry_new_name.place(x=150, y=10)

    new_pwd = tk.StringVar()
    tk.Label(window_sign_up, text=‘Password: ‘).place(x=10, y=50)
    entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show=‘*‘)
    entry_usr_pwd.place(x=150, y=50)

    new_pwd_confirm = tk.StringVar()
    tk.Label(window_sign_up, text=‘Confirm password: ‘).place(x=10, y= 90)
    entry_usr_pwd_confirm = tk.Entry(window_sign_up, textvariable=new_pwd_confirm, show=‘*‘)
    entry_usr_pwd_confirm.place(x=150, y=90)

    btn_confirm_sign_up = tk.Button(window_sign_up, text=‘Sign up‘, command=sign_to_Mofan_Python)
    btn_confirm_sign_up.place(x=150, y=130)
技術分享圖片

運行結果如下所示:

當用戶名已存在時:

技術分享圖片

當密碼輸入不一致時:

技術分享圖片

當註冊成功時:
技術分享圖片

點擊確定後註冊窗口關閉

用註冊的用戶進行登錄,彈出窗口:
技術分享圖片

Python Tkinter學習(三)