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()