摘要:已獲原作者授權原系列地址簡介為提供了繪圖功能其提供的圖形組件包括線形圓形圖片甚至其他控件控件為繪制圖形圖表編輯圖形自定義控件提供了可能在第一個例子里我們將演示如何畫一條直線方法用來繪制一條直線為以整形表示的四個坐標參數這表示所要繪制的直線連
已獲原作者授權. 原系列地址: Python Tkinter簡介
Canvas 為 Tkinter 提供了繪圖功能. 其提供的圖形組件包括 線形, 圓形, 圖片, 甚至其他控件. Canvas 控件為繪制圖形圖表, 編輯圖形, 自定義控件提供了可能.
在第一個例子里, 我們將演示如何畫一條直線. create_line(coords, options) 方法用來繪制一條直線. coords 為以整形表示的四個坐標參數: x1, y1, x2, y2 . 這表示所要繪制的直線連接了 (x1, y1) 和 (x2, y2) 這兩個點. 除坐標外, 該方法還接受其他可選的 options 參數. 在下面的例子里我們用 options 參數指定顏色為我們網站的主題色: fill=#476042 .
因為是第一個例子, 所以我們盡量做了簡化: 創建一個 canvas 對象然后在其上繪制一條水平直線. 這條直線將 canvas 分割為上下兩部分.
在傳入坐標參數時, y = int(canvas_height / 2) 這種強制轉換整形的表達式是沒有必要的, 因為 create_line() 方法也接受 float 類型作為坐標參數, float 坐標數值將被自動轉為整形. 下面是第一個例子的代碼:
from tkinter import * master = Tk() canvas_width = 80 canvas_height = 40 w = Canvas(master, width=canvas_width, height=canvas_height) w.pack() y = int(canvas_height / 2) w.create_line(0, y, canvas_width, y, fill="#476042") mainloop()
上述代碼在 Python3 下會有如下顯示:
使用 create_rectangle(coords, options) 方法可以繪制矩形. coords 參數依然表示兩個點的坐標: 第一個點為左上角坐標, 第二個點為右下角坐標.
上面的窗口是由以下示例代碼生成的:
from tkinter import * master = Tk() w = Canvas(master, width=200, height=100) w.pack() w.create_rectangle(50, 20, 150, 80, fill="#476042") w.create_rectangle(65, 35, 135, 65, fill="yellow") w.create_line(0, 0, 50, 20, fill="#476042", width=3) w.create_line(0, 100, 50, 80, fill="#476042", width=3) w.create_line(150,20, 200, 0, fill="#476042", width=3) w.create_line(150, 80, 200, 100, fill="#476042", width=3) mainloop()
下圖闡釋了上面兩個例子中 create_lines() 和 create_rectangle() 這兩個方法中, 用到的各個坐標的含義:
接下來我們將說明如何在 canvas 上繪制文字. 我們將直接修改上面的例子以作為新的示例. create_text() 方法用來在 canvas 上繪制文字. 該方法的頭兩個參數表示所要繪制的文字的坐標. 默認情況下, 文字將以此坐標為中心進行繪制. 當然, 你也可以復寫 anchor 屬性來改變文字繪制的對齊方式. 比如, anchor = NW 即為指定該點坐標為所繪文字的左上角. text 屬性用以指定具體繪制在 canvas 上的文字.
from tkinter import * canvas_width = 200 canvas_height = 100 colours = ("#476042", "yellow") box=[] for ratio in ( 0.2, 0.35 ): box.append( (canvas_width * ratio, canvas_height * ratio, canvas_width * (1 - ratio), canvas_height * (1 - ratio) ) ) master = Tk() w = Canvas(master, width=canvas_width, height=canvas_height) w.pack() for i in range(2): w.create_rectangle(box[i][0], box[i][1],box[i][2],box[i][3], fill=colours[i]) w.create_line(0, 0, # canvas 原點 box[0][0], box[0][1], # box[0] 的左上角坐標 fill=colours[0], width=3) w.create_line(0, canvas_height, # canvas 的左下角坐標 box[0][0], box[0][3], # box[0] 的左下角坐標 fill=colours[0], width=3) w.create_line(box[0][2],box[0][1], # box[0] 的右上角坐標 canvas_width, 0, # canvas 的右上角坐標 fill=colours[0], width=3) w.create_line(box[0][2], box[0][3], # box[0] 的右下角坐標 canvas_width, canvas_height, # canvas 的右下角坐標 fill=colours[0], width=3) w.create_text(canvas_width / 2, canvas_height / 2, text="Python") mainloop()
雖然從代碼上來看, 我們對之前的例子做了很大的改動, 但其所輸出的結果卻與前例相差不大, 僅僅在窗口的中間多了一個顯示 "Python" 字樣的方框:
本例中我們改用變量存儲坐標等參數, 這使得改動變的方便. 比如, 要將整個畫布的寬高設為 90 * 190, 將 box[0] 的寬高比設為 0.3, 在本例中將很容易做到, 但在之前的例子中卻要修改很多代碼.
本例運行后顯示如下窗口:
圖形 oval 是一個蛋形的曲線. 它形似橢圓, 但并不是橢圓. 事實上, oval 這個概念沒有太明確的定義. 很多不同的曲線都被叫做 oval, 他們都有如下共同點:
都是可微分的簡單 (非自相交) 凸閉曲線
他們比橢圓曲線簡單
至少有一條對稱軸
oval 這個詞源自拉丁語中的 ovum, 意為 "蛋", 這很好的描述了它: 一條描述蛋形狀的曲線. 一個 oval 由兩條半徑不同的弧線組成. 下圖是一個特殊的 oval:
我們可以使用如下方法在 canvas 中創建一個 oval:
id = C.create_oval ( x0, y0, x1, y1, option, ... )
該方法的返回值為所創建的 oval 對象在當前 canvas 上的 ID.
下面的代碼繪制了一個圓心在 (75, 75), 半徑為 25 的正圓形:
from tkinter import * canvas_width = 190 canvas_height =150 master = Tk() w = Canvas(master, width=canvas_width, height=canvas_height) w.pack() w.create_oval(50,50,100,100) mainloop()
我們可以定義一個專門用來畫正圓形的方法:
def circle(canvas, x, y, r): id = canvas.create_oval(x-r, y-r, x+r, y+r) return id交互式繪圖
我們想要創建一個可在 canvas 上手動繪圖的應用, 但 canvas 并未提供畫單個點的方法. 我們可以通過繪制小的 oval 圖形來解決這個問題:
from tkinter import * canvas_width = 500 canvas_height = 150 def paint( event ): python_green = "#476042" x1, y1 = ( event.x - 1 ), ( event.y - 1 ) x2, y2 = ( event.x + 1 ), ( event.y + 1 ) w.create_oval( x1, y1, x2, y2, fill = python_green ) master = Tk() master.title( "Painting using Ovals" ) w = Canvas(master, width=canvas_width, height=canvas_height) w.pack(expand = YES, fill = BOTH) w.bind( "繪制多邊形", paint ) message = Label( master, text = "Press and Drag the mouse to draw" ) message.pack( side = BOTTOM ) mainloop()
如果要繪制一個多邊形, 可以使用 create_polygon(x0, y0, x1, y1, x2, y2, ...) 方法. 至少要傳入三個點的坐標才可以繪制一個多邊形.
下例用該方法繪制了一個三角形:
from tkinter import * canvas_width = 200 canvas_height =200 python_green = "#476042" master = Tk() w = Canvas(master, width=canvas_width, height=canvas_height) w.pack() points = [0,0,canvas_width,canvas_height/2, 0, canvas_height] w.create_polygon(points, outline=python_green, fill="yellow", width=3) mainloop()
運行后顯示為如下窗口:
或許你在讀到這篇教程時圣誕節 馬上就到了/為時尚早. 這里我們用 Python 和 Tkinter 做一些星星來裝點我們的圣誕樹. 第一課星星幾乎沒有用到任何編程技巧:
from tkinter import * canvas_width = 200 canvas_height =200 python_green = "#476042" master = Tk() w = Canvas(master, width=canvas_width, height=canvas_height) w.pack() points = [100, 140, 110, 110, 140, 100, 110, 90, 100, 60, 90, 90, 60, 100, 90, 110] w.create_polygon(points, outline=python_green, fill="yellow", width=3) mainloop()
上例非常沒有技術含量. 如果我們要改變星星的大小或胖瘦, 該怎么辦? 上例中我們只能重新指定所有點的坐標, 這種做法乏味且易出錯. 因此, 我們用了更多的編程技巧改造了上例. 首先, 我們將星星的繪制放在一個方法體中, 并用星星的原點及兩個長度指定星星的具體形狀:
經過改造的代碼如下:
from tkinter import * canvas_width = 400 canvas_height =400 python_green = "#476042" def polygon_star(canvas, x,y,p,t, outline=python_green, fill="yellow", width = 1): points = [] for i in (1,-1): points.extend((x, y + i*p)) points.extend((x + i*t, y + i*t)) points.extend((x + i*p, y)) points.extend((x + i*t, y - i * t)) print(points) canvas.create_polygon(points, outline=outline, fill=fill, width=width) master = Tk() w = Canvas(master, width=canvas_width, height=canvas_height) w.pack() p = 50 t = 15 nsteps = 10 step_x = int(canvas_width / nsteps) step_y = int(canvas_height / nsteps) for i in range(1, nsteps): polygon_star(w,i*step_x,i*step_y,p,t,outline="red",fill="gold", width=3) polygon_star(w,i*step_x,canvas_height - i*step_y,p,t,outline="red",fill="gold", width=3) mainloop()
這個例子的運行結果更像一個X形. 很顯然, 用逐個指定坐標點的方法繪制這個圖形將無比麻煩.
create_bitmap() 方法用來繪制 bitmap. 以下 bitmap 在所有平臺上都可用:
"error", "gray75", "gray50", "gray25", "gray12", "hourglass", "info", "questhead", "question", "warning"
下例將這些 bitmap 全部都繪制在一個 canvas 上:
from tkinter import * canvas_width = 300 canvas_height =80 master = Tk() canvas = Canvas(master, width=canvas_width, height=canvas_height) canvas.pack() bitmaps = ["error", "gray75", "gray50", "gray25", "gray12", "hourglass", "info", "questhead", "question", "warning"] nsteps = len(bitmaps) step_x = int(canvas_width / nsteps) for i in range(0, nsteps): canvas.create_bitmap((i+1)*step_x - step_x/2,50, bitmap=bitmaps[i]) mainloop()
結果如下:
使用 create_image(x0, x0, options ...) 用來在 canvas 上繪制圖片. 該方法不能直接接受圖片路徑等作為參數, 而是接受一個 PhotoImage 對象作為圖片參數. PhotoImage 類用于讀取圖片, 但其只能讀取 GIF 和 PGM/PPM 格式的圖片.
from tkinter import * canvas_width = 300 canvas_height =300 master = Tk() canvas = Canvas(master, width=canvas_width, height=canvas_height) canvas.pack() img = PhotoImage(file="rocks.ppm") canvas.create_image(20,20, anchor=NW, image=img) mainloop()
上面的代碼運行后輸出如下窗口:
編寫一個方法繪制一個棋盤: checkered(canvas, line_distance), 其中: "canvas" 即 Canvas 對象, 棋盤在其上繪制; "line_distance" 為線間距.
代碼如下:
from tkinter import * def checkered(canvas, line_distance): # vertical lines at an interval of "line_distance" pixel for x in range(line_distance,canvas_width,line_distance): canvas.create_line(x, 0, x, canvas_height, fill="#476042") # horizontal lines at an interval of "line_distance" pixel for y in range(line_distance,canvas_height,line_distance): canvas.create_line(0, y, canvas_width, y, fill="#476042") master = Tk() canvas_width = 200 canvas_height = 100 w = Canvas(master, width=canvas_width, height=canvas_height) w.pack() checkered(w,10) mainloop()
上面的代碼運行后輸出如下窗口:
全系列:
[譯][Tkinter 教程01] 入門: Label 控件
[譯][Tkinter 教程02] Message 控件
[譯][Tkinter 教程03] Button 控件
[譯][Tkinter 教程04] Variable 類
[譯][Tinkter 教程05] Radiobutton 控件
[譯][Tkinter 教程06] Checkbox 控件
[譯][Tkinter 教程07] Entry 控件
[譯][Tkinter 教程08] Canvas 圖形繪制
[譯][Tkinter 教程09] Scale 控件
[譯][Tkinter 教程10] Text 控件
[譯][Tkinter 教程11] 對話框和消息框
[譯][Tkinter 教程12] 布局管理 (Pack Place Grid)
[譯][Tkinter 教程13] Mastermind 游戲
[譯][Tkinter 教程14] menu 菜單
[譯][Tkinter 教程15] event 事件綁定
譯者水平有限, 如有疏漏, 歡迎指正.
已獲得原作者授權. 原文地址: Canvas Widgets
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/41510.html
摘要:已獲原作者授權原系列地址簡介一提到這個詞很多人首先想到的是餐館里的菜單雖然餐館菜單和計算機程序中的菜單看起來一點也不像但他們確實有很多共同點在餐館中菜單列舉了所有菜品和飲料在計算機程序中菜單通過圖形界面展示了應用程序可用的命令和功能在用戶界 已獲原作者授權. 原系列地址: Python Tkinter 簡介 一提到menu這個詞, 很多人首先想到的是餐館里的菜單. 雖然餐館菜單和計算...
摘要:已獲原作者授權原系列地址控件控件用來展示一些文字短消息和控件有些類似但在展示文字方面比要靈活比如控件可以改變字體而控件只能使用一種字體它提供了一個換行對象以使文字可以斷為多行它可以支持文字的自動換行及對齊這里要澄清一下前面提到的控件可以改變 已獲原作者授權. 原系列地址: Python Tkinter Message 控件 Message 控件用來展示一些文字短消息. Message...
摘要:已獲原作者授權原系列地址簡介控件是一種標準控件用來展現不同樣式的按鈕控件被用以和用戶交互比如按鈕被鼠標點擊后某種操作被啟動和控件類似按鈕可以展示圖片或者文字不同的是控件可以指定字體控件只能使用單一的字體上的文字可以多行顯示可以將一個函數或方 已獲原作者授權. 原系列地址: Python Tkinter 簡介 Button 控件是一種標準 Tkinter 控件, 用來展現不同樣式的按鈕...
摘要:已獲原作者授權原系列地址類有些控件比如控件控件等可以通過傳入特定參數直接和一個程序變量綁定這些參數包括這種綁定是雙向的如果該變量發生改變與該變量綁定的控件也會隨之更新這些控制變量和一般的變量一樣都是用來保存某個值的但一般的變量不能被傳遞給或 已獲原作者授權. 原系列地址: Python Tkinter Variable 類 有些控件 (比如 Entry 控件, Radiobutton...
摘要:已獲原作者授權原系列地址單選按鈕是一種可在多個預先定義的選項中選擇出一項的控件單選按鈕可顯示文字或圖片顯示文字時只能使用預設字體該控件可以綁定一個函數或方法當單選按鈕被選擇時該函數或方法將被調用單選按鈕這個名字來源于收音機上的調頻按鈕這些按 已獲原作者授權. 原系列地址: Python Tkinter Radio Buttons 單選按鈕是一種可在多個預先定義的選項中選擇出一項的 T...
閱讀 3237·2021-09-07 10:10
閱讀 3582·2019-08-30 15:44
閱讀 2582·2019-08-30 15:44
閱讀 2997·2019-08-29 15:11
閱讀 2225·2019-08-28 18:26
閱讀 2748·2019-08-26 12:21
閱讀 1116·2019-08-23 16:12
閱讀 3027·2019-08-23 14:57