Python tkinter库:简易画板(笔、直线、矩形、圆形和橡皮擦工具+导入、保存、撤销、清屏功能)

您所在的位置:网站首页 手工喷壶的图片 Python tkinter库:简易画板(笔、直线、矩形、圆形和橡皮擦工具+导入、保存、撤销、清屏功能)

Python tkinter库:简易画板(笔、直线、矩形、圆形和橡皮擦工具+导入、保存、撤销、清屏功能)

2024-03-20 15:47| 来源: 网络整理| 查看: 265

Tkinter

Tkinter是Python的一款功能强大且全面、操作简易的GUI编程模块。今天,我们将使用tkinter制作一款简易画图软件。加油吧!

最终效果如下:

 

下载模块

我们将使用Python 3.10为编译器,使用 pip 下载所需模块:

pip install tkinter pip install PIL 导入模块

这里,我们将导入所有所需的模块。

import time import tkinter import tkinter.simpledialog import tkinter.colorchooser import tkinter.filedialog from PIL import Image, ImageTk, ImageGrab 设置主窗口

设置所有接下来所需的元素,并初始化。

def center_window(w, h): app.winfo_screenwidth() app.winfo_screenheight() app.geometry('%dx%d' % (w, h)) app = tkinter.Tk() app.title('轩氏画图') x = 1200 y = 800 center_window(x, y) yesno = tkinter.IntVar(value=0) what = tkinter.IntVar(value=1) X = tkinter.IntVar(value=0) Y = tkinter.IntVar(value=0) foreColor = '#000000' backColor = '#FFFFFF' image = tkinter.PhotoImage() canvas = tkinter.Canvas(app, bg='white', width=x, height=y) canvas.create_image(x, y, image=image) lastDraw = 0 end = [0] size = "20" 基本画图运算逻辑

重点来了!我们使用鼠标左键按下等动作探测,绘制曲线:

def getter(widget): time.sleep(0.5) x = app.winfo_x() + widget.winfo_x() y = app.winfo_y() + widget.winfo_y() if app.winfo_x() < 0: x = 0 if app.winfo_y() < 0: y = 0 x1 = x + widget.winfo_width() + 200 y1 = y + widget.winfo_height() + 200 filename = tkinter.filedialog.asksaveasfilename(filetypes=[('.jpg', 'JPG')], initialdir='C:\\Users\\lin042\\Desktop\\') ImageGrab.grab().crop((x, y, x1, y1)).save(filename) def onLeftButtonDown(event): yesno.set(1) X.set(event.x) Y.set(event.y) if what.get() == 4: canvas.create_text(event.x, event.y, font=("等线", int(size)), text=text, fill=foreColor) what.set(1) def onLeftButtonMove(event): global lastDraw if yesno.get() == 0: return if what.get() == 1: lastDraw = 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: try: canvas.delete(lastDraw) except Exception: pass lastDraw = canvas.create_line(X.get(), Y.get(), event.x, event.y, fill=foreColor) elif what.get() == 3: try: canvas.delete(lastDraw) except Exception: pass lastDraw = canvas.create_rectangle(X.get(), Y.get(), event.x, event.y, outline=foreColor) elif what.get() == 5: lastDraw = canvas.create_rectangle(event.x - 10, event.y - 10, event.x + 10, event.y + 10, outline=backColor) elif what.get() == 6: try: canvas.delete(lastDraw) except Exception: pass lastDraw = canvas.create_oval(X.get(), Y.get(), event.x, event.y, fill=backColor, outline=foreColor) def onLeftButtonUp(event): global lastDraw if what.get() == 2: lastDraw = canvas.create_line(X.get(), Y.get(), event.x, event.y, fill=foreColor) elif what.get() == 3: lastDraw = canvas.create_rectangle(X.get(), Y.get(), event.x, event.y, outline=foreColor) elif what.get() == 6: lastDraw = canvas.create_oval(X.get(), Y.get(), event.x, event.y, outline=foreColor) yesno.set(0) end.append(lastDraw) def onRightButtonUp(event): menu.post(event.x_root, event.y_root)

最后通过bind来移动画笔:

canvas.bind('', onLeftButtonDown) canvas.bind('', onLeftButtonMove) canvas.bind('', onLeftButtonUp) canvas.bind('', onRightButtonUp) canvas.pack(fill=tkinter.BOTH, expand=tkinter.YES) 顶部主菜单

设置主菜单功能及运算函数。目前包括以下五个选项:导入、保存、撤销、清屏和工具栏。

'''主菜单及其关联的函数''' menu = tkinter.Menu(app, bg="red") app.config(menu=menu) def Open(): filename = tkinter.filedialog.askopenfilename(title='导入图片', filetypes=[('image', '*.jpg *.png *.gif')]) if filename: global image image = Image.open(filename) image = image.resize((800, 600), Image.ANTIALIAS) image = ImageTk.PhotoImage(image) canvas.create_image(400, 300, image=image) menu.add_command(label='导入', command=Open) def Save(): getter(canvas) menu.add_command(label='保存', command=Save) def Clear(): global lastDraw, end for item in canvas.find_all(): canvas.delete(item) end = [0] lastDraw = 0 menu.add_command(label='清屏', command=Clear) def Back(): global end try: for i in range(end[-2], end[-1] + 1): canvas.delete(i) end.pop() except: end = [0] menu.add_command(label='撤销', command=Back) menu.add_separator() 工具栏子菜单

设置“工具栏”下子菜单函数和内容,运算逻辑前面已经定义过了,这里我们只需要调用并绑定按钮即可。

'''子菜单及其关联的函数''' menuType = tkinter.Menu(menu, tearoff=0) def drawCurve(): what.set(1) menuType.add_command(label='铅笔', command=drawCurve) def drawLine(): what.set(2) menuType.add_command(label='直线', command=drawLine) def drawRectangle(): what.set(3) menuType.add_command(label='矩形', command=drawRectangle) def drawCircle(): what.set(6) menuType.add_command(label='圆形', command=drawCircle) def drawText(): global text, size text = tkinter.simpledialog.askstring(title='输入文本', prompt='') if text is not None: size = tkinter.simpledialog.askinteger('输入字号', prompt='', initialvalue=20) if size is None: size = "20" what.set(4) menuType.add_command(label='文本', command=drawText) def onErase(): what.set(5) menuType.add_command(label='橡皮擦', command=onErase) menuType.add_separator() def chooseForeColor(): global foreColor foreColor = tkinter.colorchooser.askcolor()[1] menuType.add_command(label='选择前景色', command=chooseForeColor) def chooseBackColor(): global backColor backColor = tkinter.colorchooser.askcolor()[1] menuType.add_command(label='选择背景色', command=chooseBackColor) menu.add_cascade(label='工具栏', menu=menuType) 进入窗口循环

最后,使用mainloop进入窗口循环。

app.mainloop() 效果展示

最终效果展示:

 

 

 

完整代码

完整代码如下:

import time import tkinter import tkinter.simpledialog import tkinter.colorchooser import tkinter.filedialog from PIL import Image, ImageTk, ImageGrab def center_window(w, h): app.winfo_screenwidth() app.winfo_screenheight() app.geometry('%dx%d' % (w, h)) app = tkinter.Tk() app.title('轩氏画图') x = 1200 y = 800 center_window(x, y) yesno = tkinter.IntVar(value=0) what = tkinter.IntVar(value=1) X = tkinter.IntVar(value=0) Y = tkinter.IntVar(value=0) foreColor = '#000000' backColor = '#FFFFFF' image = tkinter.PhotoImage() canvas = tkinter.Canvas(app, bg='white', width=x, height=y) canvas.create_image(x, y, image=image) lastDraw = 0 end = [0] size = "20" def getter(widget): time.sleep(0.5) x = app.winfo_x() + widget.winfo_x() y = app.winfo_y() + widget.winfo_y() if app.winfo_x() < 0: x = 0 if app.winfo_y() < 0: y = 0 x1 = x + widget.winfo_width() + 200 y1 = y + widget.winfo_height() + 200 filename = tkinter.filedialog.asksaveasfilename(filetypes=[('.jpg', 'JPG')], initialdir='C:\\Users\\lin042\\Desktop\\') ImageGrab.grab().crop((x, y, x1, y1)).save(filename) def onLeftButtonDown(event): yesno.set(1) X.set(event.x) Y.set(event.y) if what.get() == 4: canvas.create_text(event.x, event.y, font=("等线", int(size)), text=text, fill=foreColor) what.set(1) def onLeftButtonMove(event): global lastDraw if yesno.get() == 0: return if what.get() == 1: lastDraw = 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: try: canvas.delete(lastDraw) except Exception: pass lastDraw = canvas.create_line(X.get(), Y.get(), event.x, event.y, fill=foreColor) elif what.get() == 3: try: canvas.delete(lastDraw) except Exception: pass lastDraw = canvas.create_rectangle(X.get(), Y.get(), event.x, event.y, outline=foreColor) elif what.get() == 5: lastDraw = canvas.create_rectangle(event.x - 10, event.y - 10, event.x + 10, event.y + 10, outline=backColor) elif what.get() == 6: try: canvas.delete(lastDraw) except Exception: pass lastDraw = canvas.create_oval(X.get(), Y.get(), event.x, event.y, fill=backColor, outline=foreColor) def onLeftButtonUp(event): global lastDraw if what.get() == 2: lastDraw = canvas.create_line(X.get(), Y.get(), event.x, event.y, fill=foreColor) elif what.get() == 3: lastDraw = canvas.create_rectangle(X.get(), Y.get(), event.x, event.y, outline=foreColor) elif what.get() == 6: lastDraw = canvas.create_oval(X.get(), Y.get(), event.x, event.y, outline=foreColor) yesno.set(0) end.append(lastDraw) def onRightButtonUp(event): menu.post(event.x_root, event.y_root) canvas.bind('', onLeftButtonDown) canvas.bind('', onLeftButtonMove) canvas.bind('', onLeftButtonUp) canvas.bind('', onRightButtonUp) canvas.pack(fill=tkinter.BOTH, expand=tkinter.YES) '''主菜单及其关联的函数''' menu = tkinter.Menu(app, bg="red") app.config(menu=menu) def Open(): filename = tkinter.filedialog.askopenfilename(title='导入图片', filetypes=[('image', '*.jpg *.png *.gif')]) if filename: global image image = Image.open(filename) image = image.resize((800, 600), Image.ANTIALIAS) image = ImageTk.PhotoImage(image) canvas.create_image(400, 300, image=image) menu.add_command(label='导入', command=Open) def Save(): getter(canvas) menu.add_command(label='保存', command=Save) def Clear(): global lastDraw, end for item in canvas.find_all(): canvas.delete(item) end = [0] lastDraw = 0 menu.add_command(label='清屏', command=Clear) def Back(): global end try: for i in range(end[-2], end[-1] + 1): canvas.delete(i) end.pop() except: end = [0] menu.add_command(label='撤销', command=Back) menu.add_separator() '''子菜单及其关联的函数''' menuType = tkinter.Menu(menu, tearoff=0) def drawCurve(): what.set(1) menuType.add_command(label='铅笔', command=drawCurve) def drawLine(): what.set(2) menuType.add_command(label='直线', command=drawLine) def drawRectangle(): what.set(3) menuType.add_command(label='矩形', command=drawRectangle) def drawCircle(): what.set(6) menuType.add_command(label='圆形', command=drawCircle) def drawText(): global text, size text = tkinter.simpledialog.askstring(title='输入文本', prompt='') if text is not None: size = tkinter.simpledialog.askinteger('输入字号', prompt='', initialvalue=20) if size is None: size = "20" what.set(4) menuType.add_command(label='文本', command=drawText) def onErase(): what.set(5) menuType.add_command(label='橡皮擦', command=onErase) menuType.add_separator() def chooseForeColor(): global foreColor foreColor = tkinter.colorchooser.askcolor()[1] menuType.add_command(label='选择前景色', command=chooseForeColor) def chooseBackColor(): global backColor backColor = tkinter.colorchooser.askcolor()[1] menuType.add_command(label='选择背景色', command=chooseBackColor) menu.add_cascade(label='工具栏', menu=menuType) app.mainloop()

喜欢就点个赞,收藏一下吧~

我是轩哥啊哈,下期我们不见不散~



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3