[Python] 纯文本查看 复制代码
from tkinter import *
from tkinter.colorchooser import *
# 窗口的全局变量 宽度与高度
win_width = 660
win_height = 380
class Application(Frame):
"""实现一个画图的小软件"""
def __init__(self, master=None, bg_color='gold', fg_color='DarkOrange'): # Gold 金 色 DarkOrange 深橙色
super().__init__(master)
self.master = master
self.bg_color = bg_color # 定义一个背景颜色的对象属性
self.fg_color = fg_color # 定义一个前景色
self.x = self.y = 0 # 起始位置的 x 与 y 初始值
self.last_draw = 0 # 表示最后绘制的图形的ID
self.start_draw_flag = False # 标记最开始的画的位置变量
self.pack()
# 下面定义按钮的一些参数
self.bin_text = {'start': '开始', 'pen': '画笔', 'rect': '画矩形', 'clear': '清屏', 'eraser': '橡皮擦',
'line': '直线', 'line_arrow': '直线(箭头)', 'color': '画笔颜色', 'bg_color': '背景颜色', 'quit': '退出'}
# 下面开始实现控件 设置一个宽度随窗口,高度为root窗口0.9倍的大小的数值,背景色设置为默认传参的 粉色
self.draw_pad = Canvas(self, width=win_width, height=win_height*0.9, bg=self.bg_color)
self.draw_pad.pack()
# 采用循环的方式创建按钮
for k, v in self.bin_text.items():
# index = self.bin_text.index(i)
self.btn = Button(self, text=v, name=k)
self.btn.pack(side='left', padx=10)
# 按钮类事件处理
self.btn.bind_class('Button', '<Button-1>', self.event_massage)
# 鼠标释放,为了解决 self.start_draw_flag为True后起点一直是一个点的问题
self.draw_pad.bind('<ButtonRelease-1>', self.stop_draw)
# 颜色快捷键的设置
root.bind('<KeyPress-r>', self.kjj) # 设置红色的快捷键
root.bind('<KeyPress-g>', self.kjj) # 设置绿的快捷键
root.bind('<KeyPress-y>', self.kjj) # 设置黄色的快捷键
# 事件管理
def event_massage(self, event):
name = event.widget.winfo_name()
# print(name)
if name == 'line':
self.draw_pad.bind('<B1-Motion>', self.my_line) # B1-Motion 是按住鼠标拖动的事件
elif name == 'line_arrow':
self.draw_pad.bind('<B1-Motion>', self.my_line_arrow) # B1-Motion 是按住鼠标拖动的事件
elif name == 'rect':
self.draw_pad.bind('<B1-Motion>', self.my_rect) # B1-Motion 是按住鼠标拖动的事件
elif name == 'pen':
self.draw_pad.bind('<B1-Motion>', self.my_pen) # B1-Motion 是按住鼠标拖动的事件
elif name == 'eraser':
self.draw_pad.bind('<B1-Motion>', self.my_eraser) # B1-Motion 是按住鼠标拖动的事件
elif name == 'color':
cor = askcolor(title='选择画笔颜色', color=self.fg_color)
self.fg_color = cor[1]
elif name == 'bg_color':
cor = askcolor(title='选择背景颜色', color=self.bg_color)
self.bg_color = cor[1]
self.draw_pad['bg'] = self.bg_color
[color=Magenta]event.widget.state = 'Disabled'[/color]
elif name == 'clear':
self.draw_pad.delete('all') # 直接清除全部就 ok 了
elif name == 'quit': # 设置程序的退出机制
root.destroy()
# 让self.start_draw_flag为初始
def stop_draw(self, event):
self.start_draw_flag = False
self.last_draw = event.x * 0 # 这样解决画新线删除旧线的问题,改变一下 Self.last_draw的值找不到原来的值my_line函数里也就删除不了了
# 重复代码精简封装一下 一个新的函数方法
def start_draw(self, event):
# 每次调用这个函数方法之前都删除掉前面的线,
# print('要删除的是什么东西?:', self.last_draw)
self.draw_pad.delete(self.last_draw)
# 判断起始位置是不是False
if not self.start_draw_flag: # 如果是False说明第一次画
self.start_draw_flag = True
self.x = event.x # 一开始的 x
self.y = event.y # 一载始的 y
# 画直线的函数方法
def my_line(self, event):
# 直接调用 start_draw方法
self.start_draw(event)
# 开始画一条直线
self.last_draw = self.draw_pad.create_line(self.x, self.y, event.x, event.y, fill=self.fg_color)
# 画带箭头的直线的函数方法
def my_line_arrow(self, event):
# 直接调用 start_draw方法
self.start_draw(event)
# 开始画一条带箭头的直线 区别是只加一个参数就可以了 就是加一个 arrow=LAST
self.last_draw = self.draw_pad.create_line(self.x, self.y, event.x, event.y, arrow=LAST, fill=self.fg_color)
# 画矩形的函数方法
def my_rect(self, event):
# 直接调用 start_draw方法
self.start_draw(event)
# # 开始画一个矩形,下面代码是全部填充的样式
# self.last_draw = self.draw_pad.create_rectangle(self.x, self.y, event.x, event.y, fill=self.fg_color)
# 开始画一个矩形,下面代码是不进行填充的样式 outline 表示的是边框颜色
self.last_draw = self.draw_pad.create_rectangle(self.x, self.y, event.x, event.y, outline=self.fg_color)
# 利用画直线 的方法进行画笔功能的实现,就是一小段一小段的直线连起来,但是要去掉self.last_draw,这样就留住了,不删除了
def my_pen(self, event):
# 直接调用 start_draw方法
self.start_draw(event)
# 开始画一条带箭头的直线 区别是只加一个参数就可以了 就是加一个 arrow=LAST
self.draw_pad.create_line(self.x, self.y, event.x, event.y, fill=self.fg_color)
# 重新给self.x 与 self.y进行赋值,这样起点就会随鼠标移动一直变化 了
self.x = event.x
self.y = event.y
# 橡皮擦
def my_eraser(self, event):
# 就是画一个背景色的矩形,下面代码是全部填充的样式
self.last_draw = self.draw_pad.create_rectangle(event.x-4, event.y-4, event.x+4, event.y+4,
outline=self.bg_color, fill=self.bg_color)
# 快捷键函数方法
def kjj(self, event):
if event.char == 'r':
self.fg_color = '#ff0000'
if event.char == 'g':
self.fg_color = '#00ff00'
if event.char == 'y':
self.fg_color = 'yellow' # #ffff00
if __name__ == '__main__':
root = Tk()
root.geometry(f'{win_width}x{win_height}+500+180')
root.title('画图小工具---> by: luxingyu329')
# root['bg'] = 'yellow'
app = Application(master=root) # 实例化对象
root.mainloop()