您好,登錄后才能下訂單哦!
本篇內容介紹了“python中Tkinter如何使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
1.1、Tkinter是什么
Tkinter 是使用 python 進行窗口視窗設計的模塊。Tkinter模塊(“Tk 接口”)是Python的標準Tk GUI工具包的接口。作為 python 特定的GUI界面,是一個圖像的窗口,tkinter是python自帶的,可以編輯的GUI界面,用來入門,熟悉窗口視窗的使用,非常有必要。
2.1、Windows演示環境搭建
安裝python3.7
安裝編輯器,演示使用的Visual Studio Code
3.1、創建出一個窗口
首先我們導入tkinter的庫
import tkinter as tk # 在代碼里面導入庫,起一個別名,以后代碼里面就用這個別名root = tk.Tk() # 這個庫里面有Tk()這個方法,這個方法的作用就是創建一個窗口
如果只是執行以上的兩句代碼,運行程序是沒有反應的,因為只有一個主函數,從上到下執行完就沒有了,這個窗口也是很快就消失了,所以現在我們要做的就是讓窗口一直顯示,那么我們就可以加一個循環
創建的窗口的名字是root ,那么我們之后使用這個root就可以操作這個窗口了。
root.mainloop() # 加上這一句,就可以看見窗口了
執行以上的3句代碼,我們就可以看見窗口了
3.2、給窗口取一個標題
root.title('演示窗口')
3.3、窗口設置
通過以下代碼,我們可以給窗口設置長寬以及窗口在屏幕的位置
root.geometry("300x100+630+80") # 長x寬+x*y
3.3、創建按鈕,并且給按鈕添加點擊事件
這個庫里面有一個方法Button(),只要調用這個方法,我們就可以創建這個組件,創建的這個組件我們賦值給一個常量,以后我們就可以用這個常量來操作這個按鈕,這個方法里面的參數,就是要我們寫窗口的名字
Button(root) 這樣寫的意思就是 將我們創建的按鈕放到這個窗口上面
btn1 = tk.Button(root)
給按鈕取一個名稱
btn1["text"] = "點擊"
我們創建的按鈕組件,已經放到窗口里面了,但是放到窗口的哪個位置,東南西北哪個地方,我們就可以用pack()去定位(后面會介紹其它定位方法)
btn1.pack() # 按鈕在窗口里面的定位
創建點擊按鈕事件的彈窗,先導入messagebox,這個必須單獨導入
from tkinter import messageboxdef test(e): messagebox.showinfo("窗口名稱","點擊成功")
現在有了按鈕,有了方法,我想要做的是一點擊按鈕,就執行這個方法,那么就需要將按鈕和方法進行綁定
btn1.bind("<Button-1>",test) #第一個參數為:按鼠標左鍵的事件 第二個參數為:要執行的方法的名字
按鈕組件里面有一個方法bind() 這個方法就可以實現綁定
完整代碼
import tkinter as tkfrom tkinter import messagebox root = tk.Tk() # 創建窗口root.title('演示窗口')root.geometry("300x100+630+80") # 長x寬+x*ybtn1 = tk.Button(root) # 創建按鈕,并且將按鈕放到窗口里面btn1["text"] = "點擊" # 給按鈕一個名稱btn1.pack() # 按鈕布局def test(e): '''創建彈窗''' messagebox.showinfo("窗口名稱", "點擊成功")btn1.bind("<Button-1>", test) # 將按鈕和方法進行綁定,也就是創建了一個事件root.mainloop() # 讓窗口一直顯示,循環
3.4、窗口內的組件布局
3種布局管理器:pack - grid - place
pack 這個布局管理器,要么將組件垂直的排列,要么水平的排列
grid Grid(網格)布局管理器會將控件放置到一個二維的表格里。 主控件被分割成一系列的行和列,表格中的每個單元(cell)都可以放置一個控件。
選項 | 說明 |
---|---|
column | 單元格的列號,從0開始的正整數 |
columnspan | 跨列,跨越的列數,正整數 |
row | 單元格的行號, 從0開始的正整數 |
rowspan | 跨行,跨越的行數,正整數 |
ipadx, ipady | 設置子組件之間的間隔,x方向或y方向,默認單位為像素,非浮點數,默認0.0 |
padx, pady | 與之并列的組件之間的間隔,x方向或y方向,默認單位為像素,非浮點數,默認0.0 |
sticky | 組件緊貼所在的單元格的某一腳,對應于東南西北中以及4個角。東 = “e”,南=“s”,西=“w”,北=“n”,“ne”,“se”,“sw”, “nw”; |
grid_info() 查看組件默認的參數
import tkinter as tk root = tk.Tk()# 默認按鈕btn1 = tk.Button(root)btn1["text"] = "按鈕1"btn1.grid()print(btn1.grid_info())root.title('演示窗口')root.geometry("300x150+1000+300")root.mainloop()
column 指定控件所在的列
import tkinter as tk root = tk.Tk()# 按鈕1btn1 = tk.Button(root)btn1["text"] = "按鈕1"btn1.grid(column=0)# 按鈕2btn2 = tk.Button(root)btn2["text"] = "按鈕2"btn2.grid(column=1)root.title('演示窗口')root.geometry("300x100+1000+300")root.mainloop()
columnspan 指定每個控件橫跨的列數
什么是columnspan?
類似excel的合并單元格
a占了兩個格子的寬度,colunmspan就是2
"python import tkinter as tk root = tk.Tk() # 按鈕1 btn1 = tk.Button(root) btn1["text"] = "按鈕1" btn1.grid(column=0, columnspan=2) # 按鈕2 btn2 = tk.Button(root) btn2["text"] = "按鈕2" btn2.grid(column=1, columnspan=1) root.title('演示窗口') root.geometry("300x100+1000+300") root.mainloop()
row 指定控件所在的行
import tkinter as tk root = tk.Tk()# 按鈕1btn1 = tk.Button(root)btn1["text"] = "按鈕1"btn1.grid(row=0)# 按鈕2btn2 = tk.Button(root)btn2["text"] = "按鈕2"btn2.grid(row=1)# 按鈕3btn3 = tk.Button(root)btn3["text"] = "按鈕2"btn3.grid(row=2)root.title('演示窗口')root.geometry("300x100+1000+300")root.mainloop()
rowspan 指定每個控件橫跨的行數
什么是rowspan ?
類似excel的合并單元格
a占了兩個格子的高度,rowspan就是2
import tkinter as tk root = tk.Tk()# 按鈕1btn1 = tk.Button(root)btn1["text"] = "按鈕1"btn1.grid(row=0, rowspan=2)# 按鈕2btn2 = tk.Button(root)btn2["text"] = "按鈕2"btn2.grid(row=2, rowspan=1)root.title('演示窗口')root.geometry("300x100+1000+300")root.mainloop()
ipadx 水平方向內邊距
import tkinter as tk root = tk.Tk()# 按鈕1btn1 = tk.Button(root)btn1["text"] = "按鈕1"btn1.grid(ipadx=20)# 按鈕2btn2 = tk.Button(root)btn2["text"] = "按鈕2"btn2.grid(ipadx=5)root.title('演示窗口')root.geometry("300x100+1000+300")root.mainloop()
ipady 垂直方向內邊距
import tkinter as tk root = tk.Tk()# 按鈕1btn1 = tk.Button(root)btn1["text"] = "按鈕1"btn1.grid(ipady=20)# 按鈕2btn2 = tk.Button(root)btn2["text"] = "按鈕2"btn2.grid(ipady=5)root.title('演示窗口')root.geometry("300x150+1000+300")root.mainloop()
padx 水平方向外邊距
import tkinter as tk root = tk.Tk()# 按鈕1btn1 = tk.Button(root)btn1["text"] = "按鈕1"btn1.grid(padx=50)# 按鈕2btn2 = tk.Button(root)btn2["text"] = "按鈕2"btn2.grid(column=1, padx=20)root.title('演示窗口')root.geometry("300x150+1000+300")root.mainloop()
pady 垂直方向外邊距
import tkinter as tk root = tk.Tk()# 按鈕1btn1 = tk.Button(root)btn1["text"] = "按鈕1"btn1.grid(pady=30)# 按鈕2btn2 = tk.Button(root)btn2["text"] = "按鈕2"btn2.grid(pady=20)root.title('演示窗口')root.geometry("300x150+1000+300")root.mainloop()
sticky 組件東南西北的方向
import tkinter as tk root = tk.Tk()# 默認按鈕btn1 = tk.Button(root)btn1["text"] = "默認按鈕演示效果"btn1.grid(ipadx=50)# 按鈕2btn2 = tk.Button(root)btn2["text"] = "按鈕2"btn2.grid(row=1, sticky="w")# 按鈕3btn3 = tk.Button(root)btn3["text"] = "按鈕3"btn3.grid(row=1, sticky="e")root.title('演示窗口')root.geometry("300x150+1000+300")root.mainloop()
place布局管理器 place布局管理器可以通過坐標精確控制組件的位置,適用于一些布局更加靈活的場景
選項 | 說明 |
---|---|
x,y | 組件左上角的絕對坐標(相當于窗口) |
relx ,rely | 組件左上角的坐標(相對于父容器) |
width , height | 組件的寬度和高度 |
relwidth , relheight | 組件的寬度和高度(相對于父容器) |
anchor | 對齊方式,左對齊“w”,右對齊“e”,頂對齊“n”,底對齊“s” |
import tkinter as tk root = tk.Tk()but1 = tk.Button(root, text="按鈕1")but1.place(relx=0.2, x=100, y=20, relwidth=0.2, relheight=0.5)root.title('演示窗口')root.geometry("300x150+1000+300")root.mainloop()
4.1、封裝
import tkinter as tk# from tkinter import ttk -下拉選擇框class GUI: def __init__(self): self.root = tk.Tk() self.root.title('演示窗口') self.root.geometry("500x200+1100+150") self.interface() def interface(self): """"界面編寫位置""" passif __name__ == '__main__': a = GUI() a.root.mainloop()
4.2、文本顯示_Label
def interface(self): """"界面編寫位置""" self.Label0 = tk.Label(self.root, text="文本顯示") self.Label0.grid(row=0, column=0)
4.3、按鈕顯示_Button
def interface(self): """"界面編寫位置""" self.Button0 = tk.Button(self.root, text="按鈕顯示") self.Button0.grid(row=0, column=0)
4.4、輸入框顯示_Entry
def interface(self): """"界面編寫位置""" self.Entry0 = tk.Entry(self.root) self.Entry0.grid(row=0, column=0)
4.5、文本輸入框顯示_Text
# pack布局 def interface(self): """"界面編寫位置""" self.w1 = tk.Text(self.root, width=80, height=10) self.w1.pack(pady=0, padx=30)# grid布局 def interface(self): """"界面編寫位置""" self.w1 = tk.Text(self.root, width=80, height=10) self.w1.grid(row=1, column=0)
4.6、復選按鈕_Checkbutton
def interface(self): """"界面編寫位置""" self.Checkbutton01 = tk.Checkbutton(self.root, text="名稱") self.Checkbutton01.grid(row=0, column=2)
4.7、單選按鈕_Radiobutton
def interface(self): """"界面編寫位置""" self.Radiobutton01 = tk.Radiobutton(self.root, text="名稱") self.Radiobutton01.grid(row=0, column=2)
4.8、下拉選擇框_Combobox
def interface(self): """"界面編寫位置""" values = ['1', '2', '3', '4'] self.combobox = ttk.Combobox( master=self.root, # 父容器 height=10, # 高度,下拉顯示的條目數量 width=20, # 寬度 state='', # 設置狀態 normal(可選可輸入)、readonly(只可選)、 disabled(禁止輸入選擇) cursor='arrow', # 鼠標移動時樣式 arrow, circle, cross, plus... font=('', 15), # 字體、字號 textvariable='', # 通過StringVar設置可改變的值 values=values, # 設置下拉框的選項 ) self.combobox.grid(padx=150)
4.9、菜單-主菜單、子菜單
import tkinter as tkfrom tkinter import Menuclass GUI: def __init__(self): self.root = tk.Tk() self.root.title('演示窗口') self.root.geometry("500x200+1100+150") # 創建主菜單實例 self.menubar = Menu(self.root) # 顯示菜單,將root根窗口的主菜單設置為menu self.root.config(menu=self.menubar) self.interface() def interface(self): """"界面編寫位置""" # 在 menubar 上設置菜單名,并關聯一系列子菜單 self.menubar.add_cascade(label="文件", menu=self.papers()) self.menubar.add_cascade(label="查看", menu=self.about()) def papers(self): """ fmenu = Menu(self.menubar): 創建子菜單實例 tearoff=1: 1的話多了一個虛線,如果點擊的話就會發現,這個菜單框可以獨立出來顯示 fmenu.add_separator(): 添加分隔符"--------" """ fmenu = Menu(self.menubar, tearoff=0) # 創建單選框 for item in ['新建', '打開', '保存', '另存為']: fmenu.add_command(label=item) return fmenu def about(self): amenu = Menu(self.menubar, tearoff=0) # 添加復選框 for item in ['項目復選框', '文件擴展名', '隱藏的項目']: amenu.add_checkbutton(label=item) return amenuif __name__ == '__main__': a = GUI() a.root.mainloop()
5.1、按鈕(Button)綁定事件
def interface(self): """"界面編寫位置""" self.Button0 = tk.Button(self.root, text="運行", command=self.event) self.Button0.grid(row=0, column=0) self.Button1 = tk.Button(self.root, text="退出", command=self.root.destroy, bg="Gray") # bg=顏色 self.Button1.grid(row=0, column=1, sticky="e", ipadx=10) def event(self): """按鈕事件""" print("運行成功")
5.2、輸入框(Entry)內容獲取
def interface(self): """"界面編寫位置""" self.entry00 = tk.StringVar() self.entry00.set("默認信息") self.entry0 = tk.Entry(self.root, textvariable=self.entry00) self.entry0.grid(row=1, column=0) self.Button0 = tk.Button(self.root, text="運行", command=self.event) self.Button0.grid(row=0, column=0) def event(self): """按鈕事件,獲取文本信息""" a = self.entry00.get() print(a)
5.2、文本輸入框(Text),寫入文本信息和清除文本信息
def interface(self): """"界面編寫位置""" self.Button0 = tk.Button(self.root, text="清除", command=self.event) self.Button0.grid(row=0, column=0) self.w1 = tk.Text(self.root, width=80, height=10) self.w1.grid(row=1, column=0) self.w1.insert("insert", "默認信息") def event(self): '''清空輸入框''' self.w1.delete(1.0, "end")
5.3、獲取復選按鈕(Checkbutton)的狀態
def interface(self): """"界面編寫位置""" self.Button0 = tk.Button(self.root, text="確定", command=self.event) self.Button0.grid(row=0, column=0) self.v1 = tk.IntVar() self.Checkbutton01 = tk.Checkbutton(self.root, text="復選框", command=self.Check_box, variable=self.v1) self.Checkbutton01.grid(row=1, column=0) self.w1 = tk.Text(self.root, width=80, height=10) self.w1.grid(row=2, column=0) def event(self): '''按鈕事件,獲取復選框的狀態,1表示勾選,0表示未勾選''' a = self.v1.get() self.w1.insert(1.0, str(a)+'\n') def Check_box(self): '''復選框事件''' if self.v1.get() == 1: self.w1.insert(1.0, "勾選"+'\n') else: self.w1.insert(1.0, "未勾選"+'\n')
5.4、清除控件
def interface(self): """"界面編寫位置""" self.Button0 = tk.Button(self.root, text="確定", command=self.event) self.Button0.grid(row=0, column=0) self.Label0 = tk.Label(self.root, text="文本顯示") self.Label0.grid(row=1, column=0) self.Entry0 = tk.Entry(self.root) self.Entry0.grid(row=2, column=0) self.w1 = tk.Text(self.root, width=80, height=10) self.w1.grid(row=3, column=0) def event(self): '''按鈕事件,清除Label、Entry、Text組件''' a = [self.Label0, self.Entry0, self.w1] for i in a: i.grid_forget()
5.5、清除復選框勾選狀態
def interface(self): """"界面編寫位置""" self.Button0 = tk.Button(self.root, text="確定", command=self.event) self.Button0.grid(row=0, column=0) self.v1 = tk.IntVar() self.Checkbutton01 = tk.Checkbutton(self.root, text="復選框", command=self.Check_box, variable=self.v1) self.Checkbutton01.grid(row=1, column=0) self.w1 = tk.Text(self.root, width=80, height=10) self.w1.grid(row=2, column=0) def event(self): '''按鈕事件,清除復選框勾選狀態''' self.Checkbutton01.deselect() def Check_box(self): '''復選框事件''' if self.v1.get() == 1: self.w1.insert(1.0, "勾選"+'\n') else: self.w1.insert(1.0, "未勾選"+'\n')
5.6、文本框(Text)內容獲取
def interface(self): """"界面編寫位置""" self.Button0 = tk.Button(self.root, text="確定", command=self.event) self.Button0.grid(row=0, column=0) self.w1 = tk.Text(self.root, width=80, height=10) self.w1.grid(row=1, column=0) def event(self): a = self.w1.get('0.0', 'end') print(a)
5.7、下拉選擇框綁定事件
def interface(self): """"界面編寫位置""" self.value = tk.StringVar() self.value.set('2') # 默認值 values = ['1', '2', '3', '4'] self.combobox = ttk.Combobox( master=self.root, # 父容器 height=10, # 高度,下拉顯示的條目數量 width=20, # 寬度 state='', # 設置狀態 normal(可選可輸入)、readonly(只可選)、 disabled(禁止輸入選擇) cursor='arrow', # 鼠標移動時樣式 arrow, circle, cross, plus... font=('', 15), # 字體 textvariable=self.value, # 通過StringVar設置可改變的值 values=values, # 設置下拉框的選項 ) # 綁定事件,下拉列表框被選中時,綁定pick()函數 self.combobox.bind("<<ComboboxSelected>>", self.pick) self.combobox.grid(padx=150) def pick(self, *args): # 處理事件,*args表示可變參數 print('選中的數據:{}'.format(self.combobox.get())) print('value的值:{}'.format(self.value.get()))
6.1、為什么要使用多線程
以下為單線程運行
def interface(self): """"界面編寫位置""" self.Button0 = tk.Button(self.root, text="確定", command=self.event) self.Button0.grid(row=0, column=0) self.w1 = tk.Text(self.root, width=80, height=10) self.w1.grid(row=1, column=0) def event(self): '''按鈕事件,一直循環''' a = 0 while True: a += 1 self.w1.insert(1.0, str(a)+'\n')
單線程下,主線程需要運行窗口,如果這個時候點擊“確定”按鈕,主線程就會去執行event方法,那界面就會出現“無響應”狀態,如果要界面正常顯示,那我們就需要用到多線程(threading)
多線程,完整代碼
import tkinter as tkimport threading # 導入多線程模塊class GUI: def __init__(self): self.root = tk.Tk() self.root.title('演示窗口') self.root.geometry("500x200+1100+150") self.interface() def interface(self): """"界面編寫位置""" self.Button0 = tk.Button(self.root, text="確定", command=self.start) self.Button0.grid(row=0, column=0) self.w1 = tk.Text(self.root, width=80, height=10) self.w1.grid(row=1, column=0) def event(self): '''按鈕事件,一直循環''' a = 0 while True: a += 1 self.w1.insert(1.0, str(a)+'\n') def start(self): self.T = threading.Thread(target=self.event) # 多線程 self.T.setDaemon(True) # 線程守護,即主進程結束后,此線程也結束。否則主進程結束子進程不結束 self.T.start() # 啟動if __name__ == '__main__': a = GUI() a.root.mainloop()
import tkinter as tkimport threadingfrom time import sleep event = threading.Event()class GUI: def __init__(self): self.root = tk.Tk() self.root.title('演示窗口') self.root.geometry("500x200+1100+150") self.interface() def interface(self): """"界面編寫位置""" self.Button0 = tk.Button(self.root, text="啟動", command=self.start) self.Button0.grid(row=0, column=0) self.Button0 = tk.Button(self.root, text="暫停", command=self.stop) self.Button0.grid(row=0, column=1) self.Button0 = tk.Button(self.root, text="繼續", command=self.conti) self.Button0.grid(row=0, column=2) self.w1 = tk.Text(self.root, width=70, height=10) self.w1.grid(row=1, column=0, columnspan=3) def event(self): '''按鈕事件,一直循環''' while True: sleep(1) event.wait() self.w1.insert(1.0, '運行中'+'\n') def start(self): event.set() self.T = threading.Thread(target=self.event) self.T.setDaemon(True) self.T.start() def stop(self): event.clear() self.w1.insert(1.0, '暫停'+'\n') def conti(self): event.set() self.w1.insert(1.0, '繼續'+'\n')if __name__ == '__main__': a = GUI() a.root.mainloop()
8.1、準備工作
a.py文件 - -界面邏輯+線程
b.py 文件 - -業務邏輯
以上文件在同一個目錄下
8.2、方法
# a.py 文件import tkinter as tkimport threadingfrom b import logic # 調用b文件中的logic類class GUI: def __init__(self): self.root = tk.Tk() self.root.title('演示窗口') self.root.geometry("500x260+1100+150") self.interface() def interface(self): """"界面編寫位置""" self.Button0 = tk.Button(self.root, text="確定執行", command=self.start, bg="#7bbfea") self.Button0.grid(row=0, column=1, pady=10) self.entry00 = tk.StringVar() self.entry00.set("") self.entry0 = tk.Entry(self.root, textvariable=self.entry00) self.entry0.grid(row=1, column=1, pady=15) self.w1 = tk.Text(self.root, width=50, height=8) self.w1.grid(row=2, column=0, columnspan=3, padx=60) def seal(self): '''把b文件的類單獨寫一個方法''' a = self.entry00.get() w1 = self.w1 logic().event(a, w1) def start(self): '''子線程無法直接執行b的類,需要把b文件單獨寫一個方法,然后執行''' self.T = threading.Thread(target=self.seal) self.T.setDaemon(True) self.T.start()if __name__ == '__main__': a = GUI() a.root.mainloop()
# b.py 文件import timeclass logic(): def __init__(self): pass def main(self, a, x): while True: y = int(a)+int(x) self.w1.insert(1.0, str(y)+'\n') time.sleep(1) x += 1 def event(self, a, w1): '''調用main的方法''' self.w1 = w1 x = 1 self.main(a, x)
“python中Tkinter如何使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。