1. 程式人生 > >Tkinter之Canvas篇

Tkinter之Canvas篇

https://blog.csdn.net/pengzhi5966885/article/details/77774820

Tkinter之Canvas篇

2017年09月01日 16:42:52 大個土豆 閱讀數:3440更多

'''

Created on 2017年8月31日

@author: Nick

'''

#_*_coding:utf-8_*_

import tkinter as tk

from tkinter import *

from openpyxl.worksheet.properties import Outline

from _tkinter import create

 

'''

Tkinter教程之Canvas篇

'''

 

def eventPrint(event):

    print('eventPrint!')

def printRect(event):

    print('rectangle')

def printLine(event):

    print('line')

 

# 提供可以用來進行繪圖的Container,支援基本的幾何元素,使用Canvas進行繪圖時,所有的操作都是通過Canvas,不是通過它的元素

# 元素的表示可以使用handle或tag。

 

if __name__ == '__main__':

    root = tk.Tk()

   

    root.wm_title('Canvas')#設定窗體標題

    root.wm_minsize(400, 400)#設定視窗最小化大小

    root.wm_maxsize(2800, 2800)#設定視窗最大化大小

    root.resizable(width=True, height=True)#設定視窗寬度不可變,高度可變

 

   

    #2、建立一個Canvas,設定其背景色為白色,大小

    cv = Canvas(root,bg = 'white',width = 100,height = 80)

    cv.pack(side = TOP)

   

   

   

    fram = Frame(root)

    cv = Canvas(fram,bg = 'white',width = 800,height = 200)

   

    #3、建立一個items,座標為(10,10,110,110),並填充顏色為紅色

    cv.create_rectangle(10,10,110,110,fill = 'red')

   

    #4、指定矩形的邊框顏色為綠色

    cv.create_rectangle(120,10,220,110,outline = 'green')

   

    #5、指定邊框的寬度

    cv.create_rectangle(230,10,330,110,outline = 'black',width = 10)

   

    #6、畫虛線

    # 使用屬性dash,這個值只能為奇數

    cv.create_rectangle(350,10,440,110,outline = 'black',width = 10,dash = 3)

   

    #7、使用畫刷填充

    # 使用屬性stipple

    cv.create_rectangle(460,10,550,110,fill = 'red',outline = 'black',width = 10,dash = 3,stipple = 'gray12')

   

    #8、修改item的座標

    # 使用Canvas的方法coords(原item,座標元組)來重新設定item的座標

    # 重新設定rt的座標(相當於移動一個item)

    rt = cv.create_rectangle(570,10,660,110,fill = 'green',outline = 'black',width = 5,dash = 7,stipple = 'gray12')

    cv.coords(rt,(680,10,770,110))

   

    #9、建立item的tags

    # 使用屬性tags設定item的tag

    # 使用Canvas的方法gettags獲取指定item的tags

    ta = cv.create_rectangle(10,120,110,220,fill = 'green',outline = 'black',width = 5,dash = 7,stipple = 'gray12',tags = 'r1')

    print(cv.gettags(ta))

   

    # 使用tags屬性指定多個tags,即重新設定tags的屬性,通過itemconfig(原item,屬性欄位)函式修改item屬性值

    cv.itemconfig(ta, tags = ('r2','r3','r4','r5'))

    cv.gettags(ta)

    print(cv.gettags(ta))

   

    cv.pack(side = LEFT)

    fram.pack(side = TOP)

   

   

    fram_1 = Frame(root)

    cv = Canvas(fram_1,bg = 'white',width = 800,height = 100)

   

    #10、多個item使用同一個tag

    cv.create_rectangle(10,10,110,110,fill = 'red',tags = ('r2','r3','r4','r5'))

    cv.create_rectangle(120,10,220,110,fill = 'black',tags ='r1')

    cv.create_rectangle(230,10,330,110,fill = 'green',tags ='r2')

   

    #fid_withtag返回所有與tag繫結的item。,返回的是item的序號元組,item編號從1開始

    cv.find_withtag('r2')

    print(cv.find_withtag('r2'))

       

    cv.pack(side = LEFT)

    fram_1.pack(side = TOP)

   

    #11、通過tag來訪問item

    # 得到了tag值也就得到了這個item,可以對這個item進行相關的設定。

    fram_2 = Frame(root)

    cv = Canvas(fram_2,bg = 'white',width = 800,height = 100)

    cv.create_rectangle(10,10,80,80,fill = 'green',tags = ('r2','r3','r4','r5'))

    cv.create_rectangle(90,10,160,80,fill = 'black',tags ='r1')

    cv.create_rectangle(170,10,240,80,fill = 'red',tags ='r3')

   

    # 將所有與tag('r3')繫結的item邊框顏色設定為藍色

    for item in cv.find_withtag('r3'):

        cv.itemconfig(item,outline = 'blue',width = 3)

   

    cv.pack(side = LEFT)

    fram_2.pack(side = TOP)

   

   

    #13、向其它item新增tag

    # 使用addtag_above、addtag_below來向上一個或下一個item新增tag

    # 第一個引數是tag值,第二個引數數需要修改的item

    fram_3 = Frame(root)

    cv = Canvas(fram_3,bg = 'white',width = 800,height = 100)

    tags_1 = cv.create_rectangle(10,10,80,80,fill = 'green',tags = ('r2','r3','r4','r5'))

    tags_2 = cv.create_rectangle(90,10,160,80,fill = 'black',tags ='r1')

    tags_3 = cv.create_rectangle(170,10,240,80,fill = 'red',tags ='r3')

 

    # 向tags_2的上一個item(tags_3)新增rt1

    cv.addtag_above('rt1', tags_2)

    # 向tags_2的下一個item(tags_1)新增rt11

    cv.addtag_below('rt11', 2)

   

    #Canvas使用了stack的技術,新建立的item總是位於前一個建立的item之上,故呼叫above時,它會查詢rt2上面的item為rt3,故rt3中添加了tag('r4'),同樣add_below會查詢下面的item。

   

    for item in [tags_1,tags_2,tags_3]:

        print(cv.gettags(item))

       

    #14、返回其它item

    # 使用find_above/find_below查詢上一個或下一個item,並通過itemconfig()函式設定屬性 

    cv.itemconfig(cv.find_above(tags_2),dash = 7,outline = 'blue',stipple = 'gray12')

    cv.itemconfig(cv.find_below(tags_2),dash = 2,outline = 'black',stipple = 'gray12')

    #Canvas使用了stack的技術,新建立的item總是位於前一個建立的item之上,故呼叫above時,它會查詢rt2上面的item為rt3,故rt3中添加了tag('r4'),同樣add_below會查詢下面的item。

 

    cv.pack(side = LEFT)

    fram_3.pack(side = TOP)

   

   

    #16、移動item

    fram_4 = Frame(root)

    cv = Canvas(fram_4,bg = 'white',width = 800,height = 100)

    rt_1 = cv.create_rectangle(10,10,80,80,fill = 'green')

    rt_2 = cv.create_rectangle(10,10,80,80,fill = 'green')

    rt_3 = cv.create_rectangle(170,10,240,80,fill = 'red',tags = ('s1','s2','s3'))

    # move可以指定x,y在相對偏移量,可以為負值

    cv.move(rt_2,80,10)

    cv.itemconfig(rt_2,fill = 'red')

   

   

    #17、刪除item

    # delete刪除給定的item

   

    #使用id刪除item

    cv.delete(1)

    #使用item名稱刪除item

    cv.delete(rt_2)

    #使用tag刪除item

    cv.delete('s1')

   

   

    cv.pack(side = LEFT)

    fram_4.pack(side = TOP)

   

   

   

    #18、縮放item

    # scale縮放item,計算公式:(coords - offset)*scale + offset

    # scale的引數為(self,xoffset,yoffset,xscale,yscale),self可以是item的名稱、id以及tag屬性

   

    fram_5 = Frame(root)

    cv = Canvas(fram_5,bg = 'white',width = 800,height = 100)

    sf = cv.create_rectangle(10,10,80,80,fill = 'green')

    sf_1 = cv.create_rectangle(90,10,160,80,fill = 'green',tags = 'r1')

   

    # 將y座標放大為原來的2位,x座標值不變

    cv.scale(sf_1,0,0,1,2)

    # 等價於

    #cv.scale(2,0,0,1,2)

    #cv.scale('r1',0,0,1,2)

   

   

    #19、繫結item與event

    ev_1 = cv.create_rectangle(170,10,240,80,fill = 'blue',tags = 'r1')

    ev_2 = cv.create_rectangle(250,10,320,80,fill = 'black',tags = 'r2')

    ev_3 = cv.create_rectangle(330,10,400,80,fill = 'red',tags = 'r3')

   

    # 使用tag_bind來繫結item與事件,tag_bind(tagOrId, sequence, func, add)

    # tagOrId可以是item名稱、tag屬性值,

    # 只有點選到矩形的邊框時才會觸發事件,不使用add引數,預設就是向這個item新增一個處理函式,它不會替換原來的事件函式,例子結果:既響應左鍵又響應右鍵

    # 只有點選到矩形的邊框時才會觸發事件

    cv.tag_bind(ev_1, '<Button-1>', eventPrint)

    cv.tag_bind('r2', '<Button-1>', eventPrint)

   

    # 繫結item與左鍵事件

    cv.tag_bind('r3','<Button-1>',printRect)

    # 繫結item與右鍵事件

    cv.tag_bind('r3','<Button-3>',printLine)

   

    # 將事件與tag('r1')繫結後,建立新的item並指定已繫結事件的tag,新建立的item同樣也與事件繫結,

    ev_3 = cv.create_rectangle(330,10,400,80,fill = 'green',tags = 'r3')

 

    cv.pack(side = LEFT)

    fram_5.pack(side = TOP)

   

   

    #20、繪製弧形

    fram_6 = Frame(root)

    cv = Canvas(fram_6,bg = 'white',width = 800,height = 50)

    # 使用預設引數建立一個ARC,結果為90度,填充色為紅色的扇形

    cv.create_arc(10,10,80,80,fill = 'red')

   

    #21、設定弧形的樣式

    # 使用三種樣式,分別建立了扇形、弓形和弧形

    d = {1:PIESLICE,2:CHORD,3:ARC}

    for i in d:

        cv.create_arc((10+80*i,10,80+80*i,80),style = d[i],fill = 'blue',outline = 'black',width = 5,dash = 7)

        print(str(i) + d[i])

 

    cv.pack(side = LEFT)

    fram_6.pack(side = TOP)

   

   

   

    fram_7 = Frame(root)

    cv = Canvas(fram_7,bg = 'white',width = 800,height = 50)

    #22、設定弧形的角度

    # 使用三種樣式,start指定起始角度;extent指定角度偏移

    for i in d:

        cv.create_arc((10+80*i,10,80+80*i,80),style = d[i],start = 30,extent = 30)

        print(str(i) + d[i])

 

    cv.pack(side = LEFT)

    fram_7.pack(side = TOP)

   

   

   

       

    #23、繪製點陣圖

    # 使用bitmap建立點陣圖create_bitmap

    # 使用bitmap屬性來指定點陣圖的名稱,這個函式的第一個引數為一個點(x,y)指定點陣圖存放位置的左上位置。

    fram_8 = Frame(root)

    cv = Canvas(fram_8,bg = 'white',width = 800,height = 100)

    d = {1:'error',2:'info',3:'question',4:'hourglass'}

    for i in d:

        cv.create_bitmap((20*i,20*i),bitmap = d[i])

 

   

    cv.pack(side = LEFT)

    fram_8.pack(side = TOP)

   

 

    root.mainloop()

   

   

    #建立第二個根視窗

    root_1 = tk.Tk()

   

    root_1.wm_title('Canvas-one')#設定窗體標題

    root_1.wm_minsize(400, 400)#設定視窗最小化大小

    root_1.wm_maxsize(2800, 2800)#設定視窗最大化大小

    root_1.resizable(width=True, height=True)#設定視窗寬度不可變,高度可變

   

   

      

    #24、繪製GIF影象

    # 建立gif影象create_image

    # 先使用PhotoImage建立GIF影象,再將image屬性來設定為新建立的img

    fram_9 = Frame(root_1)

    cv = Canvas(fram_9,bg = 'white',width = 800,height = 160)

    img = PhotoImage(file = 'C:\\Users\\Nick\\Desktop\\1.gif')

    cv.create_image((150,150),image = img)

   

    cv.pack(side = LEFT)

    fram_9.pack(side = TOP)

   

   

    #25、繪製直線

    # 建立帶箭頭的直線create_line

    # 使用arrow屬性來控制是否顯示箭頭

    # 將直線的屬性joinstyle分別設定為bevel/miter/round,測試其效果。

    fram_10 = Frame(root_1)

    cv = Canvas(fram_10,bg = 'white',width = 800,height = 160)

    d = [(0,'none','bevel'),(1,'first','miter'),(2,'last','round'),(3,'both','round')]

    for i in d:

        cv.create_line(

        (10,10 + i[0]*20,110,110+ i[0] * 20),   # 設定直線的起始、終點

        arrow = i[1],                           # 設定直線是否使用箭頭

        arrowshape = '40 40 10'                 # 設定箭頭的形狀(填充長度,箭頭長度,箭頭寬度

 

        )

    for i in d:

        cv.create_line(

        (130,10 + i[0]*30,220,110+ i[0] * 30),   # 設定直線的起始、終點

        arrow = i[1],                           # 設定直線是否使用箭頭

        arrowshape = '40 40 10',                 # 設定箭頭的形狀(填充長度,箭頭長度,箭頭寬度

        joinstyle = i[2],

        )

    cv.pack(side = LEFT)

    fram_10.pack(side = TOP)

       

    #26、繪製橢圓   

    # 繪製橢圓,使用create_oval屬性

 

    fram_11 = Frame(root_1)

    cv = Canvas(fram_11,bg = 'white',width = 800,height = 100)

    # 建立一個長200,寬100的橢圓  

    cv.create_oval((10,10,210,110),fill = 'red')

   

    cv.pack(side = LEFT)

    fram_11.pack(side = TOP)

       

   

    #27、建立多邊形

    # 建立多邊形(三角形),使用create_polygon

    fram_12 = Frame(root_1)

    cv = Canvas(fram_12,bg = 'white',width = 800,height = 160)

    # 建立一個直角三角形

    # 指定三個點的座標,三個點座標必須滿足三角形的定義。 

    cv.create_polygon((10,10,10,200,100,200),fill = 'blue')

    # 建立四邊形

    cv.create_polygon((200,10,10,100,80,200,200,200),fill = 'blue')

    cv.move(2,80,10)

   

    cv.pack(side = LEFT)

    fram_12.pack(side = TOP)

   

    #28、修飾圖形

    # 建立多邊形create_ploygon(三角形)

    # smooth/splinesteps用來修改繪製的圖形,不明白這兩個引數還有其它什麼作用。

    fram_13 = Frame(root_1)

    cv = Canvas(fram_13,bg = 'white',width = 800,height = 100)

    # 建立一個直角三角形

    cv.create_polygon((10,10,10,100,50,100),

                      smooth = True,   # 平滑處理,但未找到控制此引數的項

                      splinesteps = 0,  # 不明白是控制什麼的???

                      )

    cv.pack(side = LEFT)

    fram_13.pack(side = TOP)

   

    #29、繪製文字

    fram_14 = Frame(root_1)

    cv = Canvas(fram_14,bg = 'white',width = 800,height = 100)

    # 建立一個文字物件,預設設定為居中對齊

    # 使用anchor控制文字的位置,使用justify控制對齊方式

    cv.create_text((10,10),text = 'Hello Text,居中',anchor = W,fill = 'blue')

    cv.create_text((20,20),text = 'Hello Text,居左',anchor = W,fill = 'blue',justify = LEFT)

    cv.create_text((30,30),text = 'Hello Text,居右',anchor = W,fill = 'blue',justify = RIGHT)

    cv.pack(side = LEFT)

    fram_14.pack(side = TOP)

   

   

    #30、選中文字

    # 使用anchor元件在Canvas上的位置,預設情況下為居中對齊,這樣使用後其它的item將不能再使用button戰勝的那塊區域

    fram_15 = Frame(root_1)

    cv = Canvas(fram_15,bg = 'white',width = 800,height = 100)

    # 建立一個文字物件,預設設定為居中對齊

    # 使用anchor控制文字的位置,使用justify控制對齊方式

    txt = cv.create_text((10,10),text = 'Hello Text',anchor = W)

    # 設定文字的選中起始位置

    cv.select_from(txt,2)

    # 設定文字的選中結束位置

    cv.select_to(txt,5)

   

    cv.pack(side = LEFT)

    fram_15.pack(side = TOP)

   

   

    #31、建立元件

    fram_16 = Frame(root_1)

    cv = Canvas(fram_16,bg = 'white',width = 800,height = 100)

    # 建立一個Button物件,預設設定為居中對齊

    def printWindow():

        print('window')

    bt = Button(cv,text = 'ClickMe',command = printWindow)

    #修改button在canvas上的對齊方式

    cv.create_window((10,10),window = bt,anchor = W)

    # 新建立的line物件與button有重疊

    cv.create_line(10,10,20,20)

    # 新建立的line不在button之上,即沒有重疊

    cv.create_line(30,30,100,100)

   

    cv.pack(side = LEFT)

    fram_16.pack(side = TOP)          

   

    root_1.mainloop()