1. 程式人生 > 實用技巧 >Python-Tkinter圖形化介面設計(詳細教程 )

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

宣告:本篇文章為轉載自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函式名>)
  • 1
  • 2
  • 3
  • 4

其中較為常見的方法有: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(<事件程式碼>,<函式名>)
  • 1

其中,事件程式碼通常以半形小於號“<”和大於號“>” 界定,包括事件和按鍵等 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()