【渣譯】An Introduction To Tkinter - Canvas Widget Class Reference

原文地址:http://effbot.org/tkinterbook/canvas.htm

canvas組件為tkinter提供了結(jié)構(gòu)化的圖形繪制功能。其功能強(qiáng)大翰蠢,既能夠繪制點線面等圖形,還能夠創(chuàng)建出圖形編輯器啰劲,甚至可以根據(jù)界面設(shè)計的需要實現(xiàn)出多種多樣的自定義組件梁沧。

canvas組件的使用場景

canvas是一個通用組件,主要用來顯示和編輯圖形呈枉。

canvas組件還被經(jīng)常用來實現(xiàn)自定義組件趁尼。例如,可以在一個canvas上繪制并更新矩形框來實現(xiàn)一個進(jìn)度條猖辫。

樣例

要在canvas上畫東西酥泞,需要使用create方法來新增item。例如:

from Tkinter import *

master = Tk()

w = Canvas(master, width=200, height=100)
w.pack()

w.create_line(0, 0, 200, 100)
w.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))

w.create_rectangle(50, 25, 150, 75, fill="blue")

mainloop()

注意啃憎,在canvas中新增的item會一直存在到你刪除它芝囤。如果你想改變所畫的東西,可以通過coords辛萍、itemconfig悯姊、move等方法來修改所繪制的item,也可以通過delete方法將其刪除贩毕。例如:

i = w.create_line(xy, fill="red")

w.coords(i, new_xy) # change coordinates
w.itemconfig(i, fill="blue") # change color

w.delete(i) # remove

w.delete(ALL) # remove all items

一些概念

為了在canvas上顯示東西悯许,需要創(chuàng)建幾個canvas item,這些item會被存放在一個棧中辉阶。默認(rèn)情況下先壕,新繪制的item會被畫在所有已繪制item的最上邊,即覆蓋掉其他item谆甜。

canvas item

canvas組件支持以下標(biāo)準(zhǔn)item:

  • arc(弧垃僚、弦、扇形)
  • bitmap
  • imageBitmapImage實例或PhotoImage實例)
  • line
  • oval(圓或橢圓)
  • polygon
  • rectangle
  • text
  • window

弦规辱、扇形谆棺、橢圓、多邊形罕袋、矩形由邊和內(nèi)部區(qū)域組成改淑,邊和內(nèi)部區(qū)域均可以被設(shè)置為透明的碍岔。

window item被用來在canvas上放置其他tkinter組件,對于這些item溅固,canvas僅僅管理其幾何屬性付秕。

item類型可以使用C或C++進(jìn)行擴(kuò)展兰珍,通過Python包的形式供tkinter使用侍郭。

坐標(biāo)系統(tǒng)

canvas組件使用兩種坐標(biāo)系:window坐標(biāo)系和canvas坐標(biāo)系。windows坐標(biāo)系以窗口左上角作為原點(0, 0)掠河,而canvas坐標(biāo)系則會明確指明item在畫布上的位置亮元。通過滾動canvas,可以指明要在window上顯示canvas坐標(biāo)系上的哪一部分區(qū)域唠摹。

scrollregion屬性被用來限制canvas的滾動操作爆捞,可以這樣對其進(jìn)行設(shè)置:

canvas.config(scrollregion=canvas.bbox(ALL))

通過canvasxcanvasy方法可以將window坐標(biāo)轉(zhuǎn)換為canvas坐標(biāo),代碼如下:

def callback(event):
    canvas = event.widget
    x = canvas.canvasx(event.x)
    y = canvas.canvasy(event.y)
    print canvas.find_closest(x, y)

item標(biāo)識符:句柄和標(biāo)簽

canvas組件提供了幾個標(biāo)識item的方法:

  • item句柄(整數(shù))
  • 標(biāo)簽
  • ALL
  • CURRENT

item句柄是個整數(shù)值勾拉,用來標(biāo)識canvas中的一個item煮甥。tkinter會為每個在canvas上新創(chuàng)建的item自動分配一個句柄。item句柄可以通過整數(shù)形式或字符串形式傳遞給canvas提供的各類方法藕赞。

標(biāo)簽是附屬于item的一個象征性名稱成肘。標(biāo)簽是原始字符串,但不能包含空格斧蜕。一個item可以沒有標(biāo)簽示辈,也可以擁有多個標(biāo)簽跳芳,且一個標(biāo)簽名可以用于多個item。標(biāo)簽被item所擁有,依附于item而存在蘑志。

要為一個item增加標(biāo)簽,可以使用itemconfig方法設(shè)置item的tags屬性或通過addtag_withtag方法直接新增揽碘。item的tags屬性可接受字符串或字符串元組作為入?yún)⑵只病4a如下:

item = canvas.create_line(0, 0, 100, 100, tags="uno")
canvas.itemconfig(item, tags=("one", "two"))
canvas.addtag_withtag("three", "one")

要獲取一個特定item的所有標(biāo)簽,可使用gettags方法掀宋。要通過標(biāo)簽獲取相關(guān)item深纲,可使用find_withtag方法。代碼如下:

>>> print canvas.gettags(item)
('one', 'two', 'three')
>>> print canvas.find_withtag("one")
(1,)

canvas組件提供了兩個預(yù)定義標(biāo)簽:

  • ALL (或字符串"all")其匹配canvas中的所有item布朦。
  • CURRENT (或字符串"current")其匹配鼠標(biāo)指針?biāo)赶虻膇tem囤萤。這可以在鼠標(biāo)事件的處理中來找到觸發(fā)事件的item。

打印

tkinter組件支持向PostScript打印機(jī)進(jìn)行輸出是趴。

性能問題

canvas組件實現(xiàn)了一個直接的毀掉重來型的顯示模式(straight-forward damage/repair display model涛舍,這..有啥官方翻譯不...)。任何對canvas的修改和如Expose之類的外部事件都被認(rèn)為是對屏幕的破壞唆途。組件維護(hù)了一個dirty rectange來記錄被破壞的區(qū)域富雅。

當(dāng)?shù)谝粋€破壞事件到來時掸驱,canvas注冊一個待機(jī)任務(wù)(通過after_idle方法),該任務(wù)會在程序回到tkinter主循環(huán)時修復(fù)canvas没佑。此外也可以通過調(diào)用update_idletasks來強(qiáng)制更新canvas毕贼。

在重繪canvas時,會先分配一個與dirty rectangle尺寸一樣的像素圖(一塊內(nèi)存)蛤奢。之后遍歷canvas中的item并對其中與dirty rectangle有重疊的item進(jìn)行重繪鬼癣。最后,這塊像素圖會被復(fù)制到顯示屏上啤贩,同時存放像素圖的內(nèi)存被釋放待秃,這個復(fù)制過程在現(xiàn)代計算機(jī)上會非常快痹屹。

由于canvas僅使用了一個dirty rectangle章郁,因此可以通過強(qiáng)制更新來得到更好的性能。例如志衍,如果要同時改變畫布中不同的幾個區(qū)域暖庄,可以通過在改變后直接調(diào)用update_idletasks()來分別進(jìn)行更新,以避免回到主循環(huán)進(jìn)行重繪的時候dirty rectangle較大而不得不重繪大量其實并沒有被改變的item楼肪。

API參考手冊

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末培廓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子淹辞,更是在濱河造成了極大的恐慌医舆,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件象缀,死亡現(xiàn)場離奇詭異蔬将,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)央星,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門霞怀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人莉给,你說我怎么就攤上這事毙石。” “怎么了颓遏?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵徐矩,是天一觀的道長。 經(jīng)常有香客問我叁幢,道長滤灯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮鳞骤,結(jié)果婚禮上窒百,老公的妹妹穿的比我還像新娘。我一直安慰自己豫尽,他們只是感情好篙梢,可當(dāng)我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著美旧,像睡著了一般渤滞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上陈症,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天蔼水,我揣著相機(jī)與錄音震糖,去河邊找鬼录肯。 笑死,一個胖子當(dāng)著我的面吹牛吊说,可吹牛的內(nèi)容都是我干的论咏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼颁井,長吁一口氣:“原來是場噩夢啊……” “哼厅贪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起雅宾,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤养涮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后眉抬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贯吓,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年蜀变,在試婚紗的時候發(fā)現(xiàn)自己被綠了悄谐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡库北,死狀恐怖爬舰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情寒瓦,我是刑警寧澤情屹,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站杂腰,受9級特大地震影響垃你,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一蜡镶、第九天 我趴在偏房一處隱蔽的房頂上張望雾袱。 院中可真熱鬧,春花似錦官还、人聲如沸芹橡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽林说。三九已至,卻和暖如春屯伞,著一層夾襖步出監(jiān)牢的瞬間腿箩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工劣摇, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留珠移,地道東北人。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓末融,卻偏偏與公主長得像钧惧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子勾习,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容