Python-Tkinter圖形化介面設計(詳細教學 )

2021-03-30 07:00:06

宣告:本篇文章為轉載自https://www.jianshu.com/p/91844c5bca78,在原作者的基礎上新增目錄導航,旨在幫助大家以更高效率進行學習和開發。

Python-Tkinter 圖形化介面設計(詳細教學)

本文目錄

一.圖形化介面設計的基本理解

當前流行的計算機桌面應用程式大多數為圖形化使用者介面(Graphic User Interface,GUI),即通過滑鼠對選單、按鈕等圖形化元素觸發指令,並從標籤、對話方塊等圖型化顯示容器中獲取人機對話資訊。
Python自帶了tkinter 模組,實質上是一種流行的物件導向的GUI工具包 TK 的Python程式設計介面,提供了快速便利地建立GUI應用程式的方法。其影象化程式設計的基本步驟通常包括:

○ 匯入 tkinter 模組
○ 建立 GUI 根表單
○ 新增人機互動控制元件並編寫相應的函數。
○ 在主事件迴圈中等待使用者觸發事件響應。

二.表單控制元件佈局

2.1. 資料集匯入

根表單是影象化應用程式的根控制器,是tkinter的底層控制元件的範例。當匯入tkinter模組後,呼叫 Tk()方法可初始化一個根表單範例 root ,用 title() 方法可設定其標題文字,用geometry()方法可以設定表單的大小(以畫素為單位)。將其置於主迴圈中,除非使用者關閉,否則程式始終處於執行狀態。執行該程式,一個表單就呈現出來了。在這個主迴圈的根表單中,可持續呈現中的其他視覺化控制元件範例,監測事件的發生並執行相應的處理程式。下面是根表單呈現範例:

from tkinter import *
root= Tk()
root.title('我的第一個Python表單')
root.geometry('240x240') # 這裡的乘號不是 * ,而是小寫英文字母 x
root.mainloop()

在這裡插入圖片描述

2.2. tkinter 常用控制元件

返回目錄

常用控制元件:常用的10 多種,如下:
在這裡插入圖片描述

2.2.1 控制元件的共同屬性

返回目錄

在表單上呈現的視覺化控制元件,通常包括尺寸、顏色、字型、相對位置、浮雕樣式、圖示樣式和懸停遊標形狀等共同屬性。不同的控制元件由於形狀和功能不同,又有其特徵屬性。在初始化根表單和根表單主迴圈之間,可範例化表單控制元件,並設定其屬性。父容器可為根表單或其他容器控制元件範例。常見的控制元件共同屬性如下表:
在這裡插入圖片描述
標籤及常見屬性範例:

from  tkinter import *
root = Tk()
lb = Label(root,text='我是第一個標籤',\
        bg='#d3fbfb',\
        fg='red',\
        font=('華文新魏',32),\
        width=20,\
        height=2,\
        relief=SUNKEN)
lb.pack()
root.mainloop()

在這裡插入圖片描述
其中,標籤範例lb 在父容器root中範例化,具有程式碼中所示的text(文字)、bg(背景色)、fg(前景色)、font(字型)、width(寬,預設以字元為單位)、height(高,預設以字元為單位)和 relief(浮雕樣式)等一系列屬性。
在範例化控制元件時,範例的屬性可以「屬性=屬性值」的形式列舉列出,不區分先後次序。例如:「 text=‘我是第一個標籤’ 」顯示標籤的文字內容,「bg=’#d3fbfb’」設定背景色為十六進位制數RGB色 #d3fbfb等等。屬性值通常用文字形式表示。
當然如果這個控制元件範例只需要一次性呈現,也可以不必命名,直接範例化並佈局呈現出來,例如:

Label(root,text='我是第一個標籤',font='華文新魏').pack()

屬性 relief 為控制元件呈現出來的3D浮雕樣式,有 FLAT(平的)、RAISED(凸起的)、SUNKEN(凹陷的)、GROOVE(溝槽狀邊緣)和 RIDGE(脊狀邊緣) 5種。
在這裡插入圖片描述

2.3 控制元件佈局

返回目錄

控制元件的佈局通常有pack()、grid() 和 place() 三種方法。
pack和grid請參考:https://www.jianshu.com/p/91844c5bca78

2.3.1 place()方法

返回目錄

根據控制元件範例在父容器中的絕對或相對位置引數進行佈局。其常用佈局引數如下:
x,y:控制元件範例在根表單中水平和垂直方向上的其實位置(單位為畫素)。注意,根表單左上角為0,0,水平向右,垂直向下為正方向。
relx,rely:控制元件範例在根表單中水平和垂直方向上起始佈局的相對位置。即相對於根表單寬和高的比例位置,取值在0.0~1.0之間。
height,width:控制元件範例本身的高度和寬度(單位為畫素)。
relheight,relwidth:控制元件範例相對於根表單的高度和寬度比例,取值在0.0~1.0之間。

利用place()方法配合relx,rely和relheight,relwidth引數所得的到的介面可自適應根表單尺寸的大小。place()方法與grid()方法可以混合使用。如下例子:利用place()方法排列訊息(多行標籤)。
在這裡插入圖片描述

from tkinter import *
root = Tk()
root.geometry('320x240')

msg1 = Message(root,text='''我的水平起始位置相對錶單 0.2,垂直起始位置為絕對位置 80 畫素,我的高度是表單高度的0.4,寬度是200畫素''',relief=GROOVE)
msg1.place(relx=0.2,y=80,relheight=0.4,width=200)
root.mainloop()

三、tkinter常見控制元件的特徵屬性

3.1、文字輸入和輸出相關控制元件

文字的輸入與輸出控制元件通常包括:標籤(Label)、訊息(Message)、輸入框(Entry)、文字方塊(Text)。他們除了前述共同屬性外,都具有一些特徵屬性和功能。

○ 3.1.1 標籤(Label)和 訊息(Message)

返回目錄

除了單行與多行的不同外,屬性和用法基本一致,用於呈現文字資訊。值得注意的是:屬性text通常用於範例在第一次呈現時的固定文字,而如果需要在程式執行後發生變化,則可以使用下列方法之一實現:1、用控制元件範例的configure()方法來改變屬性text的值,可使顯示的文字發生變化;2、先定義一個tkinter的內部型別變數var=StringVar() 的值也可以使顯示文字發生變化。
看下面的一個例子:製作一個電子時鐘,用root的after()方法每隔1秒time模組以獲取系統當前時間,並在標籤中顯示出來。
方法一:利用configure()方法或config()來實現文字變化
在這裡插入圖片描述

import tkinter
import time

def gettime():
      timestr = time.strftime("%H:%M:%S") # 獲取當前的時間並轉化為字串
      lb.configure(text=timestr)   # 重新設定標籤文字
      root.after(1000,gettime) # 每隔1s呼叫函數 gettime 自身獲取時間

root = tkinter.Tk()
root.title('時鐘')

lb = tkinter.Label(root,text='',fg='blue',font=("黑體",80))
lb.pack()
gettime()
root.mainloop()

方法二:利用textvariable變數屬性來實現文字變化

import tkinter
import time

def gettime():
      var.set(time.strftime("%H:%M:%S"))   # 獲取當前時間
      root.after(1000,gettime)   # 每隔1s呼叫函數 gettime 自身獲取時間

root = tkinter.Tk()
root.title('時鐘')
var=tkinter.StringVar()

lb = tkinter.Label(root,textvariable=var,fg='blue',font=("黑體",80))
lb.pack()
gettime()
root.mainloop()

○ 3.1.2 文字方塊(Text)

文字方塊的常用方法如下:
在這裡插入圖片描述
上表位置的取值可為整數,浮點數或END(末尾),例如0.0表示第0列第0行
如下一個例子: 每隔1秒獲取一次當前日期的時間,並寫入文字方塊中,如下:本例中呼叫 datetime.now()獲取當前日期時間,用insert()方法每次從文字方塊txt的尾部(END)開始追加文字。
在這裡插入圖片描述

from tkinter import *
import time
import datetime

def gettime():
       s=str(datetime.datetime.now())+'\n'
       txt.insert(END,s)
       root.after(1000,gettime)  # 每隔1s呼叫函數 gettime 自身獲取時間

root=Tk()
root.geometry('320x240')
txt=Text(root)
txt.pack()
gettime()
root.mainloop()

○ 3.1.3 輸入框(Entry)

返回目錄

通常作為功能比較單一的接收單行文字輸入的控制元件,雖然也有許多對其中文字進行操作的方法,但通常用的只有取值方法get()和用於刪除文字的delete(起始位置,終止位置),例如:清空輸入框為delete(0,END)

3.2 按鈕(Button)

返回目錄

主要是為響應滑鼠單擊事件觸發執行程式所設的,故其除控制元件共有屬性外,屬性command是最為重要的屬性。通常,將按鈕要觸發執行的程式以函數形式預先定義,然後可以用一下兩種方法呼叫函數。Button按鈕的狀態有:'normal','active','disabled'

○ 直接呼叫函數。參數列達式為「command=函數名」,注意函數名後面不要加括號,也不能傳遞引數。如下面的command=run1:
○ 利用匿名函數呼叫函數和傳遞引數。引數的表示式為「command=lambda」:函數名(參數列)。例如下面的:"command=lambda:run2(inp1.get(),inp2.get())"。

○ 看下面的例子:1.從兩個輸入框去的輸入文字後轉為浮點數值進行加法運算,要求每次單擊按鈕產生的算是結果以文字的形式追加到文字方塊中,將原輸入框清空。2.按鈕方法一不傳引數呼叫函數run1()實現,按鈕「方法二」用lambda呼叫函數run2(x,y)同時傳遞引數實現。
在這裡插入圖片描述

from tkinter import *

def run1():
     a = float(inp1.get())
     b = float(inp2.get())
     s = '%0.2f+%0.2f=%0.2f\n' % (a, b, a + b)
     txt.insert(END, s)   # 追加顯示運算結果
     inp1.delete(0, END)  # 清空輸入
     inp2.delete(0, END)  # 清空輸入

def run2(x, y):
     a = float(x)
     b = float(y)
     s = '%0.2f+%0.2f=%0.2f\n' % (a, b, a + b)
     txt.insert(END, s)   # 追加顯示運算結果
     inp1.delete(0, END)  # 清空輸入
     inp2.delete(0, END)  # 清空輸入

root = Tk()
root.geometry('460x240')
root.title('簡單加法器')

lb1 = Label(root, text='請輸入兩個數,按下面兩個按鈕之一進行加法計算')
lb1.place(relx=0.1, rely=0.1, relwidth=0.8, relheight=0.1)
inp1 = Entry(root)
inp1.place(relx=0.1, rely=0.2, relwidth=0.3, relheight=0.1)
inp2 = Entry(root)
inp2.place(relx=0.6, rely=0.2, relwidth=0.3, relheight=0.1)

# 方法-直接呼叫 run1()
btn1 = Button(root, text='方法一', command=run1)
btn1.place(relx=0.1, rely=0.4, relwidth=0.3, relheight=0.1)

# 方法二利用 lambda 傳引數呼叫run2()
btn2 = Button(root, text='方法二', command=lambda: run2(inp1.get(), inp2.get()))
btn2.place(relx=0.6, rely=0.4, relwidth=0.3, relheight=0.1)

# 在表單垂直自上而下位置60%處起,佈局相對錶單高度40%高的文字方塊
txt = Text(root)
txt.place(rely=0.6, relheight=0.4)

root.mainloop()

3.3 無線電鈕

返回目錄

(Radiobutton)是為了響應故鄉排斥的若干單選項的單擊事件以觸發執行自定義函數所設的,該控制元件排除具有共有屬性外,還具有顯示文字(text)、返回變數(variable)、返回值(value)、響應函數名(command)等重要屬性。響應函數名「command=函數名」的用法與Button相同,函數名最後也要加括號。返回變數variable=var通常應預先宣告變數的型別var=IntVar()或var=StringVar(),在所呼叫的函數中方可用var.get()方法獲取被選中範例的value值。例如下面:
在這裡插入圖片描述

from tkinter import *
def Mysel():
      dic = {0:'甲',1:'乙',2:'丙'}
      s = "您選了" + dic.get(var.get()) + "項"
      lb.config(text = s)

root = Tk()
root.title('無線電鈕')
lb = Label(root)
lb.pack()

var = IntVar()
rd1 = Radiobutton(root,text="甲",variable=var,value=0,command=Mysel)
rd1.pack()

rd2 = Radiobutton(root,text="乙",variable=var,value=1,command=Mysel)
rd2.pack()

rd3 = Radiobutton(root,text="丙",variable=var,value=2,command=Mysel)
rd3.pack()

root.mainloop()

3.4 核取方塊

返回目錄

(Checkbutton) 是為了返回多個選項值的互動控制元件,通常不直接觸發函數的執行。該控制元件除具有共有屬性外,還具有顯示文字(text)、返回變數(variable)、選中返回值(onvalue)和未選中預設返回值(offvalue)等重要屬性。返回變數variable=var 通常可以預先逐項分別宣告變數的型別var=IntVar() (預設)或 var=StringVar(), 在所呼叫的函數中方可分別呼叫 var.get()方法 取得被選中範例的 onvalue或offvalue值。核取方塊範例通常還可分別利用 select()、deselect()和 toggle() 方法對其進行選中、清除選中和反選操作。

○ 如下的例子: 利用核取方塊實現,單擊OK,可以將選中的結果顯示在標籤上。效果如下:

在這裡插入圖片描述
○ 方法:利用函數中的 if-else 分支實現多項顯示

from tkinter import *
import tkinter

def run():
     if(CheckVar1.get()==0 and CheckVar2.get()==0 and CheckVar3.get()==0 and CheckVar4.get()==0):
         s = '您還沒選擇任何愛好專案'
     else:
         s1 = "足球" if CheckVar1.get()==1 else ""
         s2 = "籃球" if CheckVar2.get() == 1 else ""
         s3 = "游泳" if CheckVar3.get() == 1 else ""
         s4 = "田徑" if CheckVar4.get() == 1 else ""
         s = "您選擇了%s %s %s %s" % (s1,s2,s3,s4)
     lb2.config(text=s)

root = tkinter.Tk()
root.title('核取方塊')
lb1=Label(root,text='請選擇您的愛好專案')
lb1.pack()

CheckVar1 = IntVar()
CheckVar2 = IntVar()
CheckVar3 = IntVar()
CheckVar4 = IntVar()

ch1 = Checkbutton(root,text='足球',variable = CheckVar1,onvalue=1,offvalue=0)
ch2 = Checkbutton(root,text='籃球',variable = CheckVar2,onvalue=1,offvalue=0)
ch3 = Checkbutton(root,text='游泳',variable = CheckVar3,onvalue=1,offvalue=0)
ch4 = Checkbutton(root,text='田徑',variable = CheckVar4,onvalue=1,offvalue=0)

ch1.pack()
ch2.pack()
ch3.pack()
ch4.pack()

btn = Button(root,text="OK",command=run)
btn.pack()

lb2 = Label(root,text='')
lb2.pack()
root.mainloop()

3.5 列表框 與 下拉式方塊

3.5.1 列表框

返回目錄

(Listbox) 可供使用者單選或多選所列條目以形成人機互動。列表框控制元件的主要方法見下面的表:
在這裡插入圖片描述
執行自定義函數時,通常使用「範例名.surselection()」 或 「selected」 來獲取選中項的位置索引。由於列表框實質上就是將Python 的列表型別資料視覺化呈現,在程式實現時,也可直接對相關列表資料進行操作,然後再通過列表框展示出來,而不必拘泥於視覺化控制元件的方法。看下面的一個例子:實現列表框的初始化、新增、插入、修改、刪除和清空操作,如下:
在這裡插入圖片描述

from tkinter import *
def ini():
      Lstbox1.delete(0,END)
      list_items = ["數學","物理","化學","語文","外語"]
      for item in list_items:
           Lstbox1.insert(END,item)

def clear():
      Lstbox1.delete(0,END)

def ins():
      if entry.get() != '':
          if Lstbox1.curselection() == ():
              Lstbox1.insert(Lstbox1.size(),entry.get())
          else:
              Lstbox1.insert(Lstbox1.curselection(),entry.get())

def updt():
      if entry.get() != '' and Lstbox1.curselection() != ():
           selected=Lstbox1.curselection()[0]
           Lstbox1.delete(selected)
           Lstbox1.insert(selected,entry.get())

def delt():
      if Lstbox1.curselection() != ():
           Lstbox1.delete(Lstbox1.curselection())

root = Tk()
root.title('列表框實驗')
root.geometry('320x240')

frame1 = Frame(root,relief=RAISED)
frame1.place(relx=0.0)

frame2 = Frame(root,relief=GROOVE)
frame2.place(relx=0.5)

Lstbox1 = Listbox(frame1)
Lstbox1.pack()

entry = Entry(frame2)
entry.pack()

btn1 = Button(frame2,text='初始化',command=ini)
btn1.pack(fill=X)

btn2 = Button(frame2,text='新增',command=ins)
btn2.pack(fill=X)

btn3 = Button(frame2,text='插入',command=ins) # 新增和插入功能實質上是一樣的
btn3.pack(fill=X)

btn4 = Button(frame2,text='修改',command=updt)
btn4.pack(fill=X)

btn5 = Button(frame2,text='刪除',command=delt)
btn5.pack(fill=X)

btn6 = Button(frame2,text='清空',command=clear)
btn6.pack(fill=X)

root.mainloop()

3.5.2 下拉式方塊

返回目錄

(Combobox) 實質上是帶文字方塊的上拉列表框,其功能也將是Python 的列表型別資料視覺化呈現,並提供使用者單選或多選所列條目以形成人機互動。在圖形化介面設計時,由於其具有靈活的介面,因此往往比列表框更受喜愛。但該控制元件並不包含在 tkinter 模組中,而是與 TreeView、Progressbar、Separator等控制元件一同包含在tkinter 的子模組ttk中。如果使用該控制元件,應先與from tkinter import ttk 語句參照ttk子模組,然後建立下拉式方塊範例: 範例名=Combobox(根物件,[屬性列表])
指定變數var=StringVar(),並設定範例屬性 textvariable = var,values=[列表…]。下拉式方塊控制元件常用方法有:獲得所選中的選項值get()和獲得所選中的選項索引current()。
看下面的一個例子:實現四則運算計算器,將兩個運算元分別填入兩個文字方塊後,通過選擇下拉式方塊中的演演算法觸發運算,如下:
在這裡插入圖片描述

from tkinter.ttk import *

def calc(event):
       a = float(t1.get())
       b = float(t2.get())
       dic = {0:a+b,1:a-b,2:a*b,3:a/b}
       c = dic[comb.current()]
       lbl.config(text=str(c))

root = Tk()
root.title('四則運算')
root.geometry('320x240')

t1 = Entry(root)
t1.place(relx=0.1,rely=0.1,relwidth=0.2,relheight=0.1)

t2 = Entry(root)
t2.place(relx=0.5,rely=0.1,relwidth=0.2,relheight=0.1)

var = StringVar()

comb = Combobox(root,textvariable=var,values=['加','減','乘','除',])
comb.place(relx=0.1,rely=0.5,relwidth=0.2)
comb.bind('<<ComboboxSelected>>',calc)

lbl=Label(root,text='結果')
lbl.place(relx=0.5,rely=0.7,relwidth=0.2,relheight=0.3)

root.mainloop()

3.6 滾軸

返回目錄

(Scale) 是一種 直觀地進行數值輸入的互動控制元件,其主要屬性見下表:
在這裡插入圖片描述
滾軸控制元件範例的主要方法比較簡單,有 get()set(值),分別為取值和將滾軸設在某特定值上。滾軸範例也可繫結滑鼠左鍵釋放事件<ButtoonRelease-1>,並在執行函數中新增引數event來實現事件響應。
例如:在一個表單上設計一個200畫素寬的水平滾軸,取值範圍為1.0~5.0,分辨精度為0.05,刻度間隔為 1,用滑鼠拖動滾軸後釋放滑鼠可讀取滾軸值並顯示在標籤上。效果如下:
在這裡插入圖片描述

from tkinter  import  *

def show(event):
      s = '滾軸的取值為' + str(var.get())
      lb.config(text=s)

root = Tk()
root.title('滾軸實驗')
root.geometry('320x180')
var=DoubleVar()
scl = Scale(root,orient=HORIZONTAL,length=200,from_=1.0,to=5.0,label='請拖動滾軸',tickinterval=1,resolution=0.05,variable=var)
scl.bind('<ButtonRelease-1>',show)
scl.pack()

lb = Label(root,text='')
lb.pack()

root.mainloop()

3.7 選單

返回目錄

(Menu)用於視覺化地為一系列的命令分組,從而方便使用者找到和觸發執行這些命令。這裡Menu所範例化別的主要是選單,其通式為:

選單範例名=Menu(根表單)
選單分組1=Menu(選單範例名)
選單範例名.add_cascade(<label=選單分組1 顯示文字>,<menu=選單分組1>)
選單分組1.add_command(<label=命令1文字>,<command=命令1函數名>)

其中較為常見的方法有:add_cascade()add_command()add_separator(),分別用於新增一個選單分組、新增一條選單命令和新增一條分割線。
利用Menu控制元件也可以建立快捷選單(又稱為上下文選單)。通常需要右擊彈出的控制元件範例繫結滑鼠右擊響應事件,並指向一個捕獲event引數的自定義函數,在該自定義函數中,將滑鼠的觸發位置event.x_root 和 event.y_root以post()方法傳給選單。
例子: 仿照window自帶的「記事本」中的檔案和編輯 選單,實現在主選單個快捷選單上觸發選單命令,並相應改變表單上的標籤的文字內容。效果如下:
在這裡插入圖片描述

from tkinter import *

def new():
     s = '新建'
     lb1.config(text=s)

def ope():
     s = '開啟'
     lb1.config(text=s)

def sav():
     s = '儲存'
     lb1.config(text=s)

def cut():
     s = '剪下'
     lb1.config(text=s)

def cop():
     s = '複製'
     lb1.config(text=s)

def pas():
     s = '貼上'
     lb1.config(text=s)

def popupmenu(event):
     mainmenu.post(event.x_root,event.y_root)

root = Tk()
root.title('選單實驗')
root.geometry('320x240')

lb1 = Label(root,text='顯示資訊',font=('黑體',32,'bold'))
lb1.place(relx=0.2,rely=0.2)

mainmenu = Menu(root)
menuFile = Menu(mainmenu)  # 選單分組 menuFile
mainmenu.add_cascade(label="檔案",menu=menuFile)
menuFile.add_command(label="新建",command=new)
menuFile.add_command(label="開啟",command=ope)
menuFile.add_command(label="儲存",command=sav)
menuFile.add_separator()  # 分割線
menuFile.add_command(label="退出",command=root.destroy)

menuEdit = Menu(mainmenu)  # 選單分組 menuEdit
mainmenu.add_cascade(label="編輯",menu=menuEdit)
menuEdit.add_command(label="剪下",command=cut)
menuEdit.add_command(label="複製",command=cop())
menuEdit.add_command(label="貼上",command=pas())

root.config(menu=mainmenu)
root.bind('Button-3',popupmenu) # 根表單繫結滑鼠右擊響應事件
root.mainloop()

3.8 子表單

返回目錄

用Toplevel可新建一個顯示在最前面的子表單,其通式為: 字型範例名=Toplevel(根表單),子表單與根表單類似,也可設定title、geomerty等屬性,並在畫布上佈局其他控制元件。如下的例子:在根表單上建立選單,觸發建立一個新的表單
在這裡插入圖片描述

from tkinter import *

def newwind():
      winNew = Toplevel(root)
      winNew.geometry('320x240')
      winNew.title('新表單')
      lb2 = Label(winNew,text='我在新表單上')
      lb2.place(relx=0.2,rely=0.2)
      btClose=Button(winNew,text='關閉',command=winNew.destroy)
      btClose.place(relx=0.7,rely=0.5)

root = Tk()
root.title('新建表單實驗')
root.geometry('320x240')

lb1 = Label(root,text='主表單',font=('黑體',32,'bold'))
lb1.place(relx=0.2,rely=0.2)

mainmenu = Menu(root)
menuFile = Menu(mainmenu)
mainmenu.add_cascade(label='選單',menu=menuFile)
menuFile.add_command(label='新表單',command=newwind)
menuFile.add_separator()
menuFile.add_command(label='退出',command=root.destroy)

root.config(menu=mainmenu)
root.mainloop()

關閉表單程式執行的方法通常用 destory(),而不建議用 quit()。用Toplevel 所建立的子表單是非模式(Modeless)的表單,雖然初建時子表單在最前面,但根表單上的控制元件範例也是可以被操作的。

3.9 模式對話方塊(Modal)

返回目錄

是相對於前面介紹的非模式表單而言的,所彈出的對話方塊必須應答,在關閉之前無法操作其後面的其他表單。常見的模式對話方塊有訊息對話方塊、輸入對話方塊、檔案選擇對話方塊、顏色選擇對話方塊等。

3.9.1 互動對話方塊

返回目錄

(一)、訊息對話方塊: 參照 tkinter.messagebox 包,可使用訊息對話方塊函數。執行這些函數,可彈出模式訊息對話方塊,並根據使用者的響應但會一個布林值。其通式為:

訊息對話方塊函數(<title=標題文字>,<message=訊息文字>,[其他引數])

看下面的例子:單擊按鈕,彈出確認取消對話方塊,並將使用者回答顯示在標籤中。效果如下:
在這裡插入圖片描述

from tkinter import *
import tkinter.messagebox

def xz():
    answer=tkinter.messagebox.askokcancel('請選擇','請選擇確定或取消')
    if answer:
        lb.config(text='已確認')
    else:
        lb.config(text='已取消')

root = Tk()

lb = Label(root,text='')
lb.pack()
btn=Button(root,text='彈出對話方塊',command=xz)
btn.pack()
root.mainloop()

(二)、輸入對話方塊: 參照tkinter.simpledialog包,可彈出輸入對話方塊,用以接收使用者的簡單輸入。輸入對話方塊常用 askstring()、askfloat()和askfloat() 三種函數,分別用於接收字串、整數和浮點數型別的輸入。
如下面的例子:單擊按鈕,彈出輸入對話方塊,接收文字輸入顯示在表單的標籤上。如下:
在這裡插入圖片描述

from tkinter.simpledialog import *

def xz():
    s=askstring('請輸入','請輸入一串文字')
    lb.config(text=s)

root = Tk()

lb = Label(root,text='')
lb.pack()
btn=Button(root,text='彈出輸入對話方塊',command=xz)
btn.pack()
root.mainloop()

3.9.2 檔案選擇對話方塊

返回目錄

參照tkinter.filedialog包,可彈出檔案選擇對話方塊,讓使用者直觀地選擇一個或一組檔案,以供進一步的檔案操作。常用的檔案選擇對話方塊函數有 askopenfilename()、askopenfilenames()和asksaveasfilename(),分別用於進一步開啟一個檔案、一組檔案和儲存檔案。其中,askopenfilename()和asksaveasfilenamme()函數的返回值型別為包含檔案路徑的檔案名字元串,而askopenfilenames()函數的返回值型別為元組。
例如:單擊按鈕,彈出檔案選擇對話方塊(「開啟」對話方塊),並將使用者所選擇的檔案路徑和檔名顯示在表單的標籤上。如下
在這裡插入圖片描述

from tkinter import *
import tkinter.filedialog

def xz():
    filename=tkinter.filedialog.askopenfilename()
    if filename != '':
         lb.config(text='您選擇的檔案是'+filename)
    else:
         lb.config(text='您沒有選擇任何檔案')

root = Tk()

lb = Label(root,text='')
lb.pack()
btn=Button(root,text='彈出檔案選擇對話方塊',command=xz)
btn.pack()
root.mainloop()

3.9.3、顏色選擇對話方塊

返回目錄

參照tkinter.colorchooser包,可使用 askcolor()函數彈出模式顏色選擇對話方塊,讓使用者可以個性化地設定顏色屬性。該函數的返回形式為包含RGB十進位制浮點元組和RGB十六進位制字串的元組型別,例如:「((135.527343.52734375,167.65234375,186.7265625)),’#87a7ba’」。通常,可將其轉換為字串型別後,再擷取以十六進位制數表示的RGB顏色字串用於為屬性賦值。
舉例:單擊按鈕,彈出顏色選擇對話方塊,並將使用者所選擇的顏色設定為表單上標籤的背景顏色,如下:
在這裡插入圖片描述

from tkinter import *
import tkinter.colorchooser

def xz():
    color=tkinter.colorchooser.askcolor()
    colorstr=str(color)
    print('列印字串%s 切掉後=%s' % (colorstr,colorstr[-9:-2]))
    lb.config(text=colorstr[-9:-2],background=colorstr[-9:-2])

root = Tk()

lb = Label(root,text='請關注顏色的變化')
lb.pack()
btn=Button(root,text='彈出顏色選擇對話方塊',command=xz)
btn.pack()
root.mainloop()

四、事件響應

返回目錄

用tkinter 可將使用者事件與自定義函數繫結,用鍵盤或滑鼠的動作事件來響應觸發自定義函數的執行。其通式為:

控制元件範例.bind(<事件程式碼>,<函數名>)

其中,事件程式碼通常以半形小於號「<」和大於號「>」 界定,包括事件和按鍵等 2~3個部分,它們之間用減號分隔,常見事件程式碼見下表:
在這裡插入圖片描述
例如,將框架控制元件範例frame 繫結滑鼠右鍵單擊事件,呼叫自定義函數 myfunc()可表示為"frame.bind(’’,myfunc)",注意: myfunc後面沒有括號。將控制元件範例繫結到鍵盤事件和部分遊標不落在具體控制元件範例上的滑鼠事件時,還需要設定該範例執行focus_set() 方法獲得焦點,才能對事件持續響應。例如: frame.focus_set()。所呼叫的自定義函數若需要利用滑鼠或鍵盤的響應值,可將event作為引數,通過event的屬性獲取。event的屬性見下表:
在這裡插入圖片描述
在這裡插入圖片描述

from tkinter import *

def show(event):
s=event.keysym
lb.config(text=s)

root=Tk()
root.title('按鍵實驗')
root.geometry('200x200')
lb=Label(root,text='請按鍵',font=('黑體',48))
lb.bind('<Key>',show)
lb.focus_set()
lb.pack()
root.mainloop()

補充:

五、背景圖片

1、新增背景

返回目錄

#插入檔案圖片
import tkinter as tk

root = tk.Tk()

#建立一個標籤類, [justify]:對齊方式
textLabel = tk.Label(root,text="你在右邊會看到一個圖片,\n我在換個行",
justify = tk.LEFT)#左對齊
textLabel.pack(side=tk.LEFT)#自動對齊,side:方位

 

#建立一個圖片管理類
photo = tk.PhotoImage(file="18.png")#file:t圖片路徑
imgLabel = tk.Label(root,image=photo)#把圖片整合到標籤類中
imgLabel.pack(side=tk.RIGHT)#自動對齊


tk.mainloop()

在這裡插入圖片描述

返回目錄

import tkinter as tk

root = tk.Tk()


#增加背景圖片
photo = tk.PhotoImage(file="背景.png")
theLabel = tk.Label(root,
         text="我是內容,\n請你閱讀",#內容
         justify=tk.LEFT,#對齊方式
         image=photo,#加入圖片
         compound = tk.CENTER,#關鍵:設定為背景圖片
         font=("華文行楷",20),#字型和字號
         fg = "white")#前景色
theLabel.pack()

 

tk.mainloop()

在這裡插入圖片描述

返回目錄

#插入檔案圖片
import tkinter as tk

root = tk.Tk()

frame1 = tk.Frame(root)#這是上面的框架
frame2 = tk.Frame(root)#這是下面的框架


var = tk.StringVar()#儲存文字的類
var.set("你在右邊會看到一個圖片,\n我在換個行")#設定文字

#建立一個標籤類, [justify]:對齊方式,[frame]所屬框架
textLabel = tk.Label(frame1,textvariable=var,
         justify = tk.LEFT)#顯示文字內容 
textLabel.pack(side=tk.LEFT)#自動對齊,side:方位

 

#建立一個圖片管理類
photo = tk.PhotoImage(file="18.png")#file:t圖片路徑
imgLabel = tk.Label(frame1,image=photo)#把圖片整合到標籤類中
imgLabel.pack(side=tk.RIGHT)#自動對齊


def callback():#觸發的函數
  var.set("你還真按了")#設定文字

#[frame]所屬框架 ,text 文字內容 command:觸發方法
theButton = tk.Button(frame2,text="我是下面的按鈕",command=callback)
theButton.pack()#自動對齊

 

frame1.pack(padx=10,pady=10)#上框架對齊
frame2.pack(padx=10,pady=10)#下框架對齊


tk.mainloop()

在這裡插入圖片描述
在這裡插入圖片描述

返回目錄

六、開啟攝像頭,顯示

效果:
在這裡插入圖片描述
程式碼:

  from tkinter import *
    import cv2
    from PIL import Image,ImageTk
    
    
    def take_snapshot():
        print("有人給你點贊啦!")
    
    def video_loop():
        success, img = camera.read()  # 從攝像頭讀取照片
        if success:
            cv2.waitKey(100)
            cv2image = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)#轉換顏色從BGR到RGBA
            current_image = Image.fromarray(cv2image)#將影象轉換成Image物件
            imgtk = ImageTk.PhotoImage(image=current_image)
            panel.imgtk1 = imgtk
            panel.config(image=imgtk)
            root.after(1, video_loop)
    
    camera = cv2.VideoCapture(0)    #攝像頭
    
    root = Tk()
    root.title("opencv + tkinter")
    #root.protocol('WM_DELETE_WINDOW', detector)
    
    
    panel = Label(root)  # initialize image panel
    panel.pack(padx=10, pady=10)
    # root.config(cursor="arrow")
    btn = Button(root, text="點贊!", command=take_snapshot)
    btn.pack(fill="both", expand=True, padx=10, pady=10)
    
    video_loop()
    
    root.mainloop()
    # 當一切都完成後,關閉攝像頭並釋放所佔資源
    camera.release()
    cv2.destroyAllWindows()

感謝前輩:
https://www.jianshu.com/p/91844c5bca78
https://www.cnblogs.com/banzhen/p/7427201.html
https://blog.csdn.net/a1_a1_a/article/details/79981788