国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

[Tkinter 教程08] Canvas 圖形繪制

2019-11-06 06:24:51
字體:
來源:轉載
供稿:網友

簡介

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 = 80canvas_height = 40w = 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 = 200canvas_height = 100colours = ("#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, 他們都有如下共同點:

都是可微分的簡單 (非自相交) 凸閉曲線他們比橢圓曲線簡單至少有一條對稱軸

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 = 190canvas_height =150master = 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 = 500canvas_height = 150def 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( "<B1-Motion>", 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 = 200canvas_height =200python_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 = 200canvas_height =200python_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 = 400canvas_height =400python_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 = 50t = 15nsteps = 10step_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形. 很顯然, 用逐個指定坐標點的方法繪制這個圖形將無比麻煩. 這里寫圖片描述

繪制Bitmap

create_bitmap() 方法用來繪制 bitmap. 以下 bitmap 在所有平臺上都可用: “error”, “gray75”, “gray50”, “gray25”, “gray12”, “hourglass”, “info”, “questhead”, “question”, “warning” 下例將這些 bitmap 全部都繪制在一個 canvas 上:

from tkinter import *canvas_width = 300canvas_height =80master = 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 = 300canvas_height =300master = 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 = 200canvas_height = 100 w = Canvas(master, width=canvas_width, height=canvas_height)w.pack()checkered(w,10)mainloop()

上面的代碼運行后輸出如下窗口: 這里寫圖片描述


已獲得原作者授權. 原文地址


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 九江县| 庆阳市| 昆山市| 大英县| 建德市| 汨罗市| 布尔津县| 随州市| 门头沟区| 两当县| 佛山市| 台东县| 兴业县| 越西县| 河池市| 丰都县| 望谟县| 西华县| 新河县| 柞水县| 渑池县| 崇州市| 保康县| 贡山| 会理县| 成都市| 伊金霍洛旗| 通化县| 潞城市| 如皋市| 鲜城| 德昌县| 湄潭县| 上杭县| 林甸县| 常宁市| 同仁县| 同仁县| 子洲县| 兰坪| 兴和县|