Python Tkinter Canvas畫佈控件詳解

Canvas 控件具有兩個功能,首先它可以用來繪制各種圖形,比如弧形、線條、橢圓形、多邊形和矩形等,其次 Canvas 控件還可以用來展示圖片(包括位圖),我們將這些繪制在畫佈控件上的圖形,稱之為“畫佈對象”。

每一個畫佈對象都有一個“唯一身份ID”,這是 Tkinter 自動為其創建的,從而方便控制和操作這些畫佈對象。

通過 Canvas 控件創建一個簡單的圖形編輯器,讓用戶可以達到自定義圖形的目的,就像使用畫筆在畫佈上繪畫一樣,可以繪制各式各樣的形狀,從而有更好的人機交互體驗。

Canvas控件基本屬性

下面對 Canvas 控件的常用屬性做簡單的介紹,如下表所示:

屬性 方法
background(bg) 指定 Canvas 控件的背景顏色
borderwidth(bd) 指定 Canvas 控件的邊框寬度
closeenough 1. 指定一個距離,當鼠標與畫佈對象的距離小於該值時,認為鼠標位於畫佈對象上
2. 該選項是一個浮點類型的值
confine 1. 指定 Canvas 控件是否允許滾動超出 scrollregion 選項設置的滾動范圍,默認值為 True
selectbackground 指定當畫佈對象(即在 Canvas 畫佈上繪制的圖形)被選中時的背景色,
selectborderwidth 指定當畫佈對象被選中時的邊框寬度(選中邊框)
selectforeground 指定當畫佈對象被選中時的前景色
state 設置 Canvas 的狀態:"normal" 或 "disabled",默認值是 "normal",註意,該值不會影響畫佈對象的狀態
takefocus 指定使用 Tab 鍵可以將焦點移動到輸入框中,默認為開啟,將該選項設置為 False 避免焦點在此輸入框中
width 指定 Canvas 的寬度,單位為像素
xscrollcommand 與 scrollbar(滾動條)控件相關聯(沿著 x 軸水平方向)
xscrollincrement 1. 該選項指定 Canvas 水平滾動的“步長”
2. 例如 '3c' 表示 3 厘米,還可以選擇的單位有 'i'(英寸),'m'(毫米)和 'p'(DPI,大約是 '1i' 等於 '72p')
3. 默認為 0,表示可以水平滾動到任意位置
yscrollcommand 與 scrollbar 控件(滾動條)相關聯(沿著 y 軸垂直方向)
yscrollincrement 1. 該選項指定 Canvas 垂直滾動的“步長”
2. 例如 '3c' 表示 3 厘米,還可以選擇的單位有 'i'(英寸),'m'(毫米)和 'p'(DPI,大約是 '1i' 等於 '72p')
3. 默認值是 0,表示可以垂直方向滾動到任意位置

上述屬性是用來設置 Canvas 控件的,下面示例定義瞭出一張畫佈(Canvas),如下所示:

import tkinter as tk
window = tk.Tk()
window.title("C語言中文網")
window.geometry('400x200')
# 創庫不允許改變
window.resizable(0,0)
window.iconbitmap('C:/Users/Administrator/Desktop/C語言中文網logo.ico')
# 創建畫佈
canvas = tk.Canvas(window,
                   bg='#CDC9A5',
                   height=200,
                   width=300)
canvas.pack()
window.mainloop()

程序運行結果如下:

圖1:tkinter Canvas控件

Canvas控件繪圖常用方法

Cansvas 控件提供瞭一系列繪制幾何圖形的常用方法,下面對這些方法做簡單介紹:

方法 說明
create_line(x0, y0, x1, y1, … , xn, yn, options) 1. 根據給定的坐標創建一條或者多條線段;
2. 參數 x0,y0,x1,y1,…,xn,yn 定義線條的坐標;
3. 參數 options 表示其他可選參數
create_oval(x0, y0, x1, y1, options) 1. 繪制一個圓形或橢圓形;
2. 參數 x0 與 y0 定義繪圖區域的左上角坐標;參數 x1 與 y1 定義繪圖區域的右下角坐標;
3. 參數 options 表示其他可選參數
create_polygon(x0, y0, x1, y1, … , xn, yn, options) 1. 繪制一個至少三個點的多邊形;
2. 參數 x0、y0、x1、y1、…、xn、yn 定義多邊形的坐標;
3. 參數 options 表示其他可選參數
create_rectangle(x0, y0, x1, y1, options) 1. 繪制一個矩形;
2. 參數 x0 與 y0 定義矩形的左上角坐標;參數 x 與 y1 定義矩形的右下角坐標;
3. 參數 options 表示其他可選參數
create_text(x0, y0, text, options) 1. 繪制一個文字字符串。其中
2. 參數 x0 與 y0 定義文字字符串的左上角坐標,參數 text 定義文字字符串的文字;
3. 參數 options 表示其他可選參數
create_image(x, y, image) 1. 創建一個圖片;
2. 參數 x 與 y 定義圖片的左上角坐標;
3. 參數 image 定義圖片的來源,必須是 tkinter 模塊的 BitmapImage 類或 PhotoImage 類的實例變量。
create_bitmap(x, y, bitmap) 1. 創建一個位圖;
2. 參數 x 與 y 定義位圖的左上角坐標;
3. 參數 bitmap 定義位圖的來源,參數值可以是 gray12、gray25、gray50、gray75、hourglass、error、questhead、info、warning 或 question,或者也可以直接使用 XBM(X Bitmap)類型的文件,此時需要在 XBM 文件名稱前添加一個 @ 符號,例如 [email protected]
create_arc(coord, start, extent, fill) 1. 繪制一個弧形;
2. 參數 coord 定義畫弧形區塊的左上角與右下角坐標;
3. 參數 start 定義畫弧形區塊的起始角度(逆時針方向);
4. 參數 extent 定義畫弧形區塊的結束角度(逆時針方向);
5. 參數 fill 定義填充弧形區塊的顏色。

註意:上述方法都會返回一個畫佈對象的唯一 ID。關於 options 參數,下面會通過一個示例對經常使用的參數做相關介紹。(但由於可選參數較多,並且每個方法中的參數作用大同小異,因此對它們不再逐一列舉)

從上述表格不難看出,Canvas 控件采用瞭坐標系的方式來確定畫佈中的每一點。一般情況下,默認主窗口的左上角為坐標原點,這種坐標系被稱作為“窗口坐標系”,但也會存在另外一種情況,即畫佈的大小可能大於主窗口,當發生這種情況的時,可以采用帶滾動條的 Canvas 控件,此時會以畫佈的左上角為坐標原點,我們將這種坐標系稱為“畫佈坐標系”。

繪制直線

下面示例展示瞭如何在畫佈(Canvas控件)上繪制一條虛線和實線,代碼如下:

from tkinter import *
root = Tk()
# 設置窗口的背景顏色以區別畫佈
root.config(bg='#87CEEB')
root.title("C語言中文網")
root.geometry('450x350')
root.iconbitmap('C:/Users/Administrator/Desktop/C語言中文網logo.ico')
# 設置畫佈的背景顏色為白色
cv=Canvas(root,bg="white",width =300, height = 250)
# 將控件放置在主窗口中
cv.pack()
# 設置坐標點,此處可以元組的形式來設置坐標點
point=[(10,20),(20,30),(30,40),(40,100),(80,120),(150,90)]
# 創建畫佈,添加線條
# fill 參數指定填充的顏色,如果為空字符串,則表示透明
# dash 參數表示用來繪制虛線輪廓,元組參數,分別代表虛線中線段的長度和線段之間的間隔
# arrow 設線段的箭頭樣式,默認不帶箭頭,參數值 first 表示添加箭頭帶線段開始位置,last表示到末尾占位置,both表示兩端均添加
# smooth 佈爾值參數,表示是否以曲線的樣式劃線,默認為 False
# width 控制線寬
line1=cv.create_line(point,fill="purple",dash=(1,1),arrow=LAST,width=5)
print('線段line1的畫佈id號:',line1)
line2=cv.create_line(point,fill="red",arrow=BOTH,smooth=TRUE,width=5)
print('線段line2的畫佈id號:',line2)
# 移動其中一條線段,隻需要更改其坐標就可以,使用 coords()方法移動曲線
cv.coords(line2,50,30,25,35,35,40,50,120,60,170,10,180)
# 顯示窗口
root.mainloop()

程序運行的最終結果,見下圖:

圖1:tkinter Canvas控件

上述示例中涉及瞭一部分參數,比如 fill、dash、arrow 等,下表對 create_line() 函數的相關參數做瞭簡單介紹:

屬性 說明
activedash 當畫佈對象狀態為 "active" 的時候,繪制虛線
activefill 當畫佈對象狀態為 "active" 的時候,填充顏色
activestipple 當畫佈對象狀態為 "active" 的時候,指定填充的位圖
activewidth 當畫佈對象狀態為 "active" 的時候,指定邊框的寬度
arrow 1. 默認線段是不帶箭頭的,通過設置該選項添加箭頭到線段中
2. "first" 表示添加箭頭到線段開始的位置
3. "last" 表示添加箭頭到線段結束的位置
4. "both" 表示兩端均添加箭頭
arrowshape 1. 用一個三元組來指定箭頭的形狀,默認值是 (8, 10, 3),元組中的數值分別代表箭頭中三條邊的長度
capstyle 1. 指定線段兩端的樣式,默認值是 "butt"
2. 該選項的值可以是:
"butt"(線段的兩段平切於起點和終點)
"projecting"(線段的兩段在起點和終點的位置將 width 選項設置的長度分別延長一半)
"round"(線段的兩段在起點和終點的位置將 width設置的長度分別延長一半,並以圓角進行繪制)
dash 繪制虛線,該選項值是一個整數元組,元組中的元素分別代表短線的長度和間隔,比如 (3, 5) 代表 3 個像素的短線和 5 個像素的間隔
dashoffset 指定虛線開始的偏移位置,比如 dash=(5, 1, 2, 1),dashoffset=3,則從 2 開始畫虛線
disableddash 當畫佈對象狀態為 "disabled" 的時候,繪制虛線
disabledfill 當畫佈對象狀態為 "disabled" 的時候,填充顏色
disabledstipple 當畫佈對象狀態為 "disabled" 的時候,指定填充的位圖
disabledwidth 當畫佈對象狀態為 "disabled" 的時候,指定邊框的寬度
fill 1. 指定填充的顏色,空字符串表示透明
joinstyle 1. 指定當繪制兩個相鄰線段之間時接口的樣式,默認為 "round"
2. 該選項的值可以是:
"round"(以連接點為圓心,1/2 width 選項設置的長度為半徑來繪制圓角)
"bevel"(在連接點處將兩線段的夾角做平切操作)
"miter"(沿著兩線段的夾角延伸至一個點)
offset 指定當點畫模式時填充位圖的偏移
smooth 默認值為 False,若設置為 True,表示將以曲線的樣式代替所繪線段
splinesteps 當繪制曲線的時,該選項指定由多少條折線來構成曲線,默認值是 12,這裡需要註意,隻有當 smooth 選項為 True 時該選項才會生效。
state 指定該畫佈對象的狀態,默認值為 "normal",參數值有 "normal","disabled"(不可用)和 "hidden"(隱藏)三種狀態。
stipple 指定一個位圖進行填充,默認值為空字符串,表示實心
tags 為創建的畫佈對象添加標簽
width 指定邊框的寬度

對於扇形、矩形、三角形、圓形等,這些封閉式圖形,它們由輪廓線和填充顏色兩部分組成。在繪制這些圖形時相關函數的可選參數與上述表格也存在略微差異,下面以繪制扇形的 create_arc() 函數為例做簡單的介紹:

屬性 方法
activedash 當畫佈對象狀態為 "active" 的時候,繪制虛線
activefill 當畫佈對象狀態為 "active" 的時候,填充顏色
activeoutline 當畫佈對象狀態為 "active" 的時候,繪制輪廓線
activeoutlinestipple 當畫佈對象狀態為 "active" 的時候,指定填充輪廓的位圖
activestipple 當畫佈對象狀態為 "active" 的時候,指定填充的位圖
activewidth 當畫佈對象狀態為 "active" 的時候,指定邊框的寬度
dash 指定繪制虛線輪廓,與繪制線段的含義相同
dashoffset 指定虛線輪廓開始的偏移位置
disableddash 當畫佈對象狀態為 "disabled" 的時候,繪制虛線
disabledfill 當畫佈對象狀態為 "disabled" 的時候,填充顏色
disabledoutline 當畫佈對象狀態為 "disabled" 的時候,繪制輪廓線
disabledoutlinestipple 當畫佈對象狀態為 "disabled" 的時候,指定填充輪廓的位圖
disabledstipple 當畫佈對象狀態為 "disabled" 的時候,指定填充的位圖
disabledwidth 當畫佈對象狀態為 "disabled" 的時候,指定邊框的寬度
extent 指定跨度(從 start 選項指定的位置開始到結束位置的角度)默認值是 90.0
fill 與上述表格的含義相同,表示指定的填充顏色,若為空字符串則為透明色
offset 指定當點畫模式時填充位置的偏移,參數值為 "x,y"坐標偏移和位置偏移兩種方式,比如 "ne"/"e" 等
outline 指定輪廓的顏色
outlineoffset 指定當點畫模式繪制輪廓時位圖的偏移
outlinestipple 當 outline 選項被設置時,該選項用於指定一個位圖來填充邊框,默認值是空字符串,表示黑色
start 指定起始位置的偏移角度
style  默認創建的是扇形,指定該方法創建的是扇形("pieslice")、弓形("chord")還是弧形("arc")
tags 為創建的畫佈對象添加標簽
width 指定邊框的寬度

在實際的使用的過程中經常用到的參數有 dash、fill、outline、extend 和 start,但是這麼多的參數我們也不可能都記住,這時查手冊是一種很好的方法,官網文檔地址:點擊前往。

下面讓我們來一組繪制幾何圖形的簡單示例:

from tkinter import *
root = Tk()
# 設置主窗口區的背景顏色以區別畫佈區的顏色
root.config(bg='#8DB6CD')
root.title("C語言中文網")
root.geometry('500x400')
root.iconbitmap('C:/Users/Administrator/Desktop/C語言中文網logo.ico')
# 將畫佈設置為白色
canvas = Canvas(root,width = 400,height = 400,bg='white')
# 設置基準坐標
x0,y0,x1,y1 = 10,10,80,80
# 繪制扇形,起始角度為 0 度,結束角度為 270, 扇形區域填充色為淡藍色,輪廓線為藍色,線寬為 2px
arc = canvas.create_arc(x0, y0, x1, y1,start = 0, extent = 270, fill = '#B0E0E6',outline ='blue',width = 2)
# 繪制圓形
oval = canvas.create_oval(x0+150, y0, x1+150, y1,fill ='#CD950C',outline = 'blue',width=2)
# 繪制矩形,並將輪廓線設置為透明色,即不顯示最外圍的輪廓線,默認為黑色
rect = canvas.create_rectangle(x0,y0+100,x1,y1+100,fill='red',outline = '')
# 繪制一個三角形,填充色為綠色
trigon = canvas.create_polygon(80,80,150,80,200,200, outline="", fill="green",)
# 當然也可以繪制一個任意多邊形,隻要你的坐標正確就可以
# 繪制一個多邊形,首先定義一系列的多邊形上的坐標點
poly_points=[(0,280),(140,200),(140,240),(270,240),(270,320),(140,320),(140,360)]
polygon = canvas.create_polygon(poly_points,fill="#BF3EFF")
# 放置畫佈在主窗口
canvas.pack()
# 顯示窗口
root.mainloop()

程序運行結果如下所示:

圖2:tkinter繪制幾何圖形

註意:create_rectangle() 方法的前兩個參數決定瞭矩形的左上角坐標,後兩個參數決定瞭矩形的右下角坐標;另外 create_oval() 方法並不是隻能繪制圓形,還能繪制橢圓形,這取決於傳入的參數。

除瞭能夠繪制幾何圖形之外,Tkinter 還可以展示圖片、創建位圖以及文本信息等,示例如下所示:

from tkinter import *
root=Tk()
# # 設置主窗口區的背景顏色以區別畫佈區的顏色
root.config(bg='#8DB6CD')
root.title("C語言中文網")
root.geometry('500x300')
root.iconbitmap('C:/Users/Administrator/Desktop/C語言中文網logo.ico')
# # 將畫佈設置為白色
cv = Canvas(root,bg='white')
# tkinter 提供的內置位圖名稱
bitmaps = ["error", "gray75", "gray50", "gray25", "gray12",
"hourglass", "info", "questhead", "question", "warning"]
# 列出所有的位圖樣式
for i in range(len(bitmaps)):
    # 前兩個參數指定一個位圖的位置,後續依次排列
    cv.create_bitmap((i+1)*30,30,bitmap=bitmaps[i])
#並在畫佈上添加文本
# 參數說明,前兩個參數(x0,y0)參照點,指定文字字符串的左上角坐標
# anchor 指定瞭文本的對於參照點的相對位置,以方位來指定,比如 W/E/N/S等
cv.create_text(30,80,text = "tkinter內置位圖預覽",fill ='#7CCD7C',anchor = W,font =('微軟雅黑',15,'bold'))
# 展示圖片,使用 PhotoImage()來加載圖片
img = PhotoImage (file="C:/Users/Administrator/Desktop/c.biancheng.gif")
cv.create_image(30,150,image = img,anchor =W)
cv.create_text(30,220,text = "圖片預覽",fill ='#7CCD7C',anchor = W,font =('微軟雅黑',15,'bold'))
cv.pack()
mainloop()

程序運行結果如下:

圖3:tkinter Canvas控件

註意,添加到 Canvas 上的對象會一直保留直著。如果你希望修改它們,您可以使用 coords() 和 move() 方法來移動畫佈上的對象,當然您可以使用 delete() 來刪除它們,示例如下:

from tkinter import *
root=Tk()
# # 設置主窗口區的背景顏色以區別畫佈區的顏色
root.config(bg='#8DB6CD')
root.title("C語言中文網")
root.geometry('500x300')
root.iconbitmap('C:/Users/Administrator/Desktop/C語言中文網logo.ico')
# 定義移動函數
def move_img():
    # 定義移動坐標
    cv.move(image1,50,30)
# # 將畫佈設置為白色
cv = Canvas(root,bg='white')
# 使用 PhotoImage()來加載圖片
img = PhotoImage (file="C:/Users/Administrator/Desktop/c.biancheng.gif")
image1=cv.create_image(30,150,image = img,anchor =W)
# 將按鈕放置在畫佈中
btn=Button(cv,text="點擊移動畫佈",bg="#8A8A8A",activebackground="#7CCD7C",command=move_img)
# 在指定位置創建一個窗口控件,tags來添加標簽
cv.create_window(365,250,height=30,width=30,window=btn)
# 調用delete() 刪除畫佈對象,若傳入ALL,則刪除所有的畫佈對象
#cv.delete(image1)
cv.pack()
# 顯示窗口
root.mainloop()

程序運行結果如下:

圖4:移動畫佈對象

註意:使用畫佈控件允許用戶自己進行繪圖,但這需要與 tkinter 事件機制相配合才能實現,在後續會做相關介紹。

到此這篇關於Python Tkinter Canvas畫佈控件詳解的文章就介紹到這瞭,更多相關Python Tkinter Canvas內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: