03-tkinter-Canve畫布使用

1. 概述

1.1 案例說(shuō)明

本案例是完成一個(gè)簡(jiǎn)易的畫板工具强品,通過(guò)本案例的練習(xí)來(lái)熟悉單選、復(fù)選清女、列表以及組合框的使用。
該簡(jiǎn)易的畫板工具具備基本的繪圖晰筛、清除以及顏色設(shè)置功能嫡丙。如下面圖片所示:


image.png

2. 菜單以及畫布的基本使用

照舊,在進(jìn)行案例代碼編寫前读第,先花點(diǎn)時(shí)間完成下面2個(gè)代碼段的練習(xí)曙博,熟悉這些組件的使用方法。

2.1 menu菜單

import tkinter
window = tkinter.Tk()
window.title('my window')
window.geometry('200x150')

l = tkinter.Label(window, text='', bg='pink', width=10)
l.pack()
counter = 0


def do():
    global counter
    l.config(text='do ' + str(counter))
    counter += 1


# 創(chuàng)建一個(gè)菜單欄怜瞒,這里我們可以把他理解成一個(gè)容器父泳,在窗口的上方
menubar = tkinter.Menu(window)
# 定義一個(gè)空菜單單元
filemenu = tkinter.Menu(menubar, tearoff=0)
# 將上面定義的空菜單命名為`File`,放在菜單欄中吴汪,就是裝入那個(gè)容器中
menubar.add_cascade(label='File', menu=filemenu)
# 在`File`中加入`New`的小菜單惠窄,即我們平時(shí)看到的下拉菜單,每一個(gè)小菜單對(duì)應(yīng)命令操作浇坐。
# 如果點(diǎn)擊這些單元, 就會(huì)觸發(fā)`do`的功能
filemenu.add_command(label='New', command=do)
# 在`File`中加入`Open`小菜單
filemenu.add_command(label='Open', command=do)
# 在`File`中加入`Save`小菜單
filemenu.add_command(label='Save', command=do)
# 這里是一條分割線
filemenu.add_separator()
# 在`File`中加入`Exit`小菜單,對(duì)應(yīng)命令為`window.quit`退出
filemenu.add_command(label='Exit', command=window.quit)

# 子菜單定義睬捶,`File`上創(chuàng)建一個(gè)空的菜單
submenu = tkinter.Menu(filemenu)
# 給放入的菜單`submenu`命名為`Import`
filemenu.add_cascade(label='Import', menu=submenu, underline=0)
# 這里和上面也一樣黔宛,在`Import`中加入一個(gè)小菜單命令`Submenu1`
submenu.add_command(label="Submenu1", command=do)
submenu.add_command(label="Submenu2", command=do)

editmenu = tkinter.Menu(menubar, tearoff=0)
menubar.add_cascade(label='Edit', menu=editmenu)
editmenu.add_command(label='Cut', command=do)
editmenu.add_command(label='Copy', command=do)
editmenu.add_command(label='Paste', command=do)


window.config(menu=menubar)
window.mainloop()

運(yùn)行結(jié)果如下:


image.png

2.2 canve畫布

import tkinter
app = tkinter.Tk()
app.title('my window')
app.geometry('200x200')
# 創(chuàng)建畫布近刘,并設(shè)置背景顏色,以及畫布長(zhǎng)寬
canvas = tkinter.Canvas(app, bg='#b9b9f9', height=150, width=200)
# 定義圖片
image_file = tkinter.PhotoImage(file='1.gif')
# 將圖片放置在畫布上
image = canvas.create_image(150, 10,
                            anchor='nw',  # 把圖片的左上角作為錨定點(diǎn)
                            image=image_file)
x0, y0, x1, y1 = 50, 50, 80, 80
# 繪制直線臀晃,從(50, 50)到(50, 80)
line = canvas.create_line(50, 80, 140, 80)
# 繪制圓形
oval = canvas.create_oval(50, 50, 80, 80, fill='pink')
# 繪制扇形
arc = canvas.create_arc(x0+30, y0+30, x1+30, y1+30, start=0, extent=180)
# 繪制矩形
rect = canvas.create_rectangle(50, 30, 100+50, 30+20)
canvas.pack()


def moveit():
    canvas.move(oval, 2, 0)


b = tkinter.Button(app, text='move', command=moveit).pack()
app.mainloop()

運(yùn)行結(jié)果如下:


image.png

3. 案例代碼實(shí)現(xiàn)

import tkinter
from tkinter import colorchooser


app = tkinter.Tk()
app.title('My Paint')
app['width'] = 800
app['height'] = 600

# 控制是否允許畫圖的變量觉渴,1:允許,0:不允許
yesno = tkinter.IntVar(value=0)
# 控制畫圖類型的變量徽惋,1:曲線案淋,2:直線,3:矩形
what = tkinter.IntVar(value=1)
# 記錄鼠標(biāo)位置的變量
X = tkinter.IntVar(value=0)
Y = tkinter.IntVar(value=0)
# 前景色
foreColor = '#000000'
backColor = '#FFFFFF'
# 創(chuàng)建畫布
image = tkinter.PhotoImage()
canvas = tkinter.Canvas(app, bg='white', width=800, height=600)
canvas.create_image(800, 600, image=image)


# 鼠標(biāo)左鍵單擊险绘,允許畫圖
def onLeftButtonDown(event):
    yesno.set(1)
    X.set(event.x)
    Y.set(event.y)


canvas.bind('<Button-1>', onLeftButtonDown)

# 記錄最后繪制圖形的id
lastDraw = 0


# 按住鼠標(biāo)左鍵移動(dòng)踢京,畫圖
def onLeftButtonMove(event):
    if yesno.get() == 0:
        return
    if what.get() == 1:
        # 使用當(dāng)前選擇的前景色繪制曲線
        canvas.create_line(X.get(), Y.get(), event.x, event.y, fill=foreColor)
        X.set(event.x)
        Y.set(event.y)
    elif what.get() == 2:
        # 繪制直線,先刪除剛剛畫過(guò)的直線宦棺,再畫一條新的直線
        global lastDraw
        try:
            canvas.delete(lastDraw)
        except Exception as e:
            pass
        lastDraw = canvas.create_line(X.get(), Y.get(), event.x, event.y,
                                      fill=foreColor)
    elif what.get() == 3:
        # 繪制矩形瓣距,先刪除剛剛畫過(guò)的矩形,再畫一個(gè)新的矩形
        # global lastDraw
        lastDraw
        try:
            canvas.delete(lastDraw)
        except Exception as e:
            pass
        lastDraw = canvas.create_rectangle(X.get(), Y.get(), event.x, event.y,
                                           fill=backColor, outline=foreColor)


canvas.bind('<B1-Motion>', onLeftButtonMove)


# 鼠標(biāo)左鍵抬起代咸,不允許畫圖
def onLeftButtonUp(event):
    if what.get() == 2:
        # 繪制直線
        canvas.create_line(X.get(), Y.get(), event.x, event.y, fill=foreColor)
    elif what.get() == 3:
        # 繪制矩形
        canvas.create_rectangle(X.get(), Y.get(), event.x, event.y,
                                fill=backColor, outline=foreColor)
    yesno.set(0)
    global lastDraw
    lastDraw = 0


canvas.bind('<ButtonRelease-1>', onLeftButtonUp)

# 創(chuàng)建菜單
menu = tkinter.Menu(app, tearoff=0)


# 添加菜單蹈丸,清除
def clear():
    for item in canvas.find_all():
        canvas.delete(item)


menu.add_command(label='Clear', command=clear)
# 添加分割線
menu.add_separator()
# 創(chuàng)建子菜單,用來(lái)選擇繪圖類型
menuType = tkinter.Menu(menu, tearoff=0)


def draw_curve():
    what.set(1)
    print(what.get())


menuType.add_command(label='Curve', command=draw_curve)


def draw_line():
    what.set(2)


menuType.add_command(label='Line', command=draw_line)


def draw_rectangle():
    what.set(3)


menuType.add_command(label='Rectangle', command=draw_rectangle)
menuType.add_separator()


# 選擇前景色
def chooseForeColor():
    global foreColor
    foreColor = tkinter.colorchooser.askcolor()[1]


menuType.add_command(label='Choose Foreground Color', command=chooseForeColor)


# 選擇背景色
def chooseBackColor():
    global backColor
    backColor = tkinter.colorchooser.askcolor()[1]


menuType.add_command(label='Choose Background Color', command=chooseBackColor)
menu.add_cascade(label='Type', menu=menuType)


# 鼠標(biāo)右鍵抬起,彈出菜單
def onRightButtonUp(event):
    menu.post(event.x_root, event.y_root)


canvas.bind('<ButtonRelease-3>', onRightButtonUp)
canvas.pack(fill=tkinter.BOTH, expand=tkinter.YES)

app.mainloop()


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末逻杖,一起剝皮案震驚了整個(gè)濱河市奋岁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌荸百,老刑警劉巖闻伶,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異够话,居然都是意外死亡虾攻,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門更鲁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)霎箍,“玉大人,你說(shuō)我怎么就攤上這事澡为∑担” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵媒至,是天一觀的道長(zhǎng)顶别。 經(jīng)常有香客問(wèn)我,道長(zhǎng)拒啰,這世上最難降的妖魔是什么驯绎? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮谋旦,結(jié)果婚禮上剩失,老公的妹妹穿的比我還像新娘。我一直安慰自己册着,他們只是感情好拴孤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著甲捏,像睡著了一般演熟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上司顿,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天芒粹,我揣著相機(jī)與錄音,去河邊找鬼大溜。 笑死化漆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的猎提。 我是一名探鬼主播获三,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼旁蔼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了疙教?” 一聲冷哼從身側(cè)響起棺聊,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贞谓,沒(méi)想到半個(gè)月后限佩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡裸弦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年祟同,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片理疙。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晕城,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出窖贤,到底是詐尸還是另有隱情砖顷,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布赃梧,位于F島的核電站滤蝠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏授嘀。R本人自食惡果不足惜物咳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蹄皱。 院中可真熱鬧览闰,春花似錦、人聲如沸夯接。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)盔几。三九已至,卻和暖如春掩幢,著一層夾襖步出監(jiān)牢的瞬間逊拍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工际邻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留芯丧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓世曾,卻偏偏與公主長(zhǎng)得像缨恒,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

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

  • 大雪紛飛中骗露,盤點(diǎn)一年來(lái)的收獲似乎還在昨天岭佳,雪未到,今天已是2019最后一天萧锉,一邊驚嘆光陰匆匆飛逝珊随,一邊著手...
    小水月閱讀 540評(píng)論 0 3
  • 20170701更換使用64位日文Windows7版,Office2007的配置筆記本柿隙,安裝CPC離線客戶端叶洞,希望...
    simtech2win閱讀 5,808評(píng)論 0 0
  • 兩只老虎跑得快, 一群鴨子下河里禀崖。 窗后風(fēng)吹草動(dòng)見(jiàn)衩辟, 門前大橋下小狗跳。 遠(yuǎn)望山谷不見(jiàn)邊波附, 近望天空易看見(jiàn)惭婿。 記念...
    王密亮閱讀 413評(píng)論 0 1