python图形界面化编程GUI(四)记事本项目和画图软件项目

本文详细介绍了如何使用Tkinter库在Python中实现记事本项目,包括菜单、文本编辑、文件操作和颜色选择,以及一个基础的画板工具,涉及界面布局、事件管理与功能实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记事本项目

通过具体的项目和案例来具体操作tkinter的组件以及相关的应用。
先创建画布的框架,然后把需要的组件放在画纸上,再把画纸放到画布上。创建组件的时候按照主菜单、子菜单的顺序依次创建,进行布局,然后再写点击时实现的函数,再对菜单进行绑定。

from tkinter import *
from tkinter.messagebox import *  # 导入消息框
from tkinter.filedialog import *  # 导入文件管理,打开,保存以及右键功能等
from tkinter.colorchooser import * # 导入颜色选择

# 创建一个类继承自frame组件,把Frame当作画纸,窗口root当作画板
class Application(Frame):
    #窗口放置的位置,初始化init方法,master指类放在哪里
    def __init__(self,master=None):
        # 继承自父类的init方法
        super().__init__(master)
        self.master = master
        # 创建实例化方法直接应用
        self.creatWidget()

    # 创建相应组件,进行摆放
    def creatWidget(self):
        # 创建主菜单,放在窗口上
        menuber = Menu(root)
        # 创建子菜单
        menuFile = Menu(menuber)  # 文件菜单
        menuEdit = Menu(menuber)  # 编辑菜单
        menuHelp = Menu(menuber)  # 帮助菜单

        # 子菜单加入到主菜单种
        menuber.add_cascade(label='文件(F)', menu=menuFile)
        menuber.add_cascade(label='编辑(E)', menu=menuEdit)
        menuber.add_cascade(label='帮助(H)', menu=menuHelp)

        # 添加菜单项,在标签后添加快捷键的说明,绑定命令
        menuFile.add_command(label='新建', accelerator='ctrl+n', command=self.newfile)
        menuFile.add_command(label='打开', accelerator='ctrl+o', command=self.openfile)
        menuFile.add_command(label='保存', accelerator='ctrl+s', command=self.savefile)
        menuFile.add_separator()  # 添加分割线
        menuFile.add_command(label='退出', accelerator='ctrl+q', command=self.quitfile)

        # 将主菜单添加到窗口上
        root['menu'] = menuber

        # 添加快捷键的处理,方法里没有时间的形参,bind绑定时,调用函数的时候需要加上形参event
        root.bind('<Control-n>',lambda event: self.newfile())
        root.bind('<Control-o>',lambda event: self.openfile())
        root.bind('<Control-s>',lambda event: self.savefile())
        root.bind('<Control-q>',lambda event: self.quitfile())

        # 文本编辑区
        self.textpad = Text(root,width=50,height=30)
        self.textpad.pack()

        # 创建上下文菜单
        self.contextMenu = Menu(root)
        self.contextMenu.add_command(label='背景颜色',command=self.openAskcolor) # 绑定颜色函数

        # 右键绑定事件
        root.bind('<Button-3>',self.createContextMenu)

    # 新建文件
    def newfile(self):
        # 提示把之前的内容另存为,然后再保存,清空,
        self.filename = asksaveasfilename(title='另存为',initialfile='未命名.txt',filetypes=[('文本文档','*.txt')],
                                        defaultextension='.txt')
        self.savefile()
        self.textpad.delete(1.0, END)  # 把text控件中所有内容清空,好比新建房子清楚地面内容

    # 打开文件
    def openfile(self):
        # 打开前需要先清空之前文本框的内容
        self.textpad.delete(1.0, END)  # 把text控件中所有内容清空,好比新建房子清楚地面内容
        # 写入内容,打开某个文件
        with askopenfile(title='打开文本文件') as f:
            # 从文件中读取到的内容插入到当前的文本框中
            self.textpad.insert(INSERT,f.read())
            # 文件名称就是打开的文件
            self.filename = f.name

    # 保存文件
    def savefile(self):
        # 打开的文件
        with open(self.filename, 'w') as f:
            #从当前的文本框中获取所有的内容
            content = self.textpad.get(1.0,END)
            f.write(content)

    # 退出
    def quitfile(self):
        root.quit()

    # 背景颜色
    def openAskcolor(self):
        # 默认为蓝色,
        bg = askcolor(color='blue',title='选择背景颜色')
        # 当前背景框为选择的颜色,gb返回的是元组的形式,第一个内容是RGB的形式,第二个元素是十六进制的形式
        self.textpad.config(bg=bg[1])
        root.config(bg=bg[1])  # 填充文本框外部,画布的颜色
    # 创建上下文菜单的函数,在鼠标右键点击的位置显示
    def createContextMenu(self,event):
        #在鼠标右击的地方传递所对应的x和y的坐标
        self.contextMenu.post(event.x_root,event.y_root)

if __name__ == '__main__':
    root = Tk()
    root.geometry('500x300+200+300')
    root.title('记事本')
    # 通过类创建的实例对象放到root窗口上
    Application(master=root)
    # 窗口的消息循环,等待用户操作
    root.mainloop()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
v
在这里插入图片描述
在这里插入图片描述

画板工具项目

实现画板工具基本的选项设置
在这里插入图片描述
第一步先实现界面的布局样式,第二步写出对应的逻辑,实现相应的功能,第三步把界面和功能进行绑定联系起来。当点击按钮触发对应的逻辑。
在这里插入图片描述

from tkinter import *
from tkinter.messagebox import *  # 导入消息框
from tkinter.filedialog import *  # 导入文件管理,打开,保存以及右键功能等
from tkinter.colorchooser import * # 导入颜色选择

# 创建一个类继承自frame组件,把Frame当作画纸,窗口root当作画板
class Application(Frame):
    #窗口放置的位置,初始化init方法,master指类放在哪里
    def __init__(self,master=None):
        # 继承自父类的init方法
        super().__init__(master)
        self.master = master
        # 创建实例化方法直接应用
        self.creatWidget()
        self.fgcolor = '#ff0000' # 默认的画笔颜色
        self.bgcolor = '#000000' # 当前画板工具默认的背景颜色
        # 开始绘制时候的状态及坐标值,如绘制直线时开始和最后的坐标及最后停留的位置
        self.x = 0
        self.y = 0  # 开始绘制时的坐标值
        # 最后的一次绘制的位置
        self.lastDraw = 0
        # 绘制的状态,是第一笔画,如第一次画直线,第二次画矩形
        self.firstDrawFlag = False



    # 创建相应组件,进行摆放
    def creatWidget(self):
        # 创建画图区域
        self.DrawArea = Canvas(root,width=900,height=500,bg='#000000')
        self.DrawArea.pack()
        # 创建按钮
        # name是为按钮起了个名字,当鼠标进行点击的时候不用再另外的判断了
        # 当鼠标按下的时候,一直都是当前按钮的操作,不需要每次画同样的图形都要先点击一下了
        # 点击其他按钮再进行图形的切换,方便后面进行if判断
        btn_start = Button(root, text='开始', name='start')
        btn_start.pack(side='left', padx=10)  # 间距为10,与之并列组件之间的间隔
        btn_pen = Button(root, text='画笔', name='pen')
        btn_pen.pack(side='left', padx=10)
        btn_rect = Button(root, text='矩形', name='rect')
        btn_rect.pack(side='left', padx=10)
        btn_clear = Button(root, text='清屏', name='clear')
        btn_clear.pack(side='left', padx=10)
        btn_eraser = Button(root, text='橡皮', name='eraser')
        btn_eraser.pack(side='left', padx=10)
        btn_line = Button(root, text='直线', name='line')
        btn_line.pack(side='left', padx=10)
        btn_lineArrow = Button(root, text='箭头直线', name='lineArrow')
        btn_lineArrow.pack(side='left', padx=10)
        btn_color = Button(root, text='颜色', name='color')
        btn_color.pack(side='left', padx=10)

        # 为矩形框按钮绑定左键点击时,触发事件管理,all表示同级按钮都触发
        btn_rect.bind_all('<Button-1>', self.eventMange)
        # 为绘图区域绑定 松开鼠标,停止绘画
        self.DrawArea.bind('<ButtonRelease-1>', self.stopDraw)


    # 事件管理,实现组件对应的方法
    def eventMange(self,event):
        # 获取当前组件的名字
        name = event.widget.winfo_name()
        if name == 'start': # 执行开始的代码
            self.DrawArea.bind('<B1-Motion>', self.startDraw)
        elif name == 'pen':
            self.DrawArea.bind('<B1-Motion>', self.pen)
        elif name == 'rect':
            self.DrawArea.bind('<B1-Motion>', self.rect) # 对名字绑定绘制矩形框
        elif name == 'clear':
            self.DrawArea.delete('all')
        elif name == 'eraser':
            self.DrawArea.bind('<B1-Motion>', self.eraser)
        elif name == 'line':
            self.DrawArea.bind('<B1-Motion>', self.myline)
        elif name == 'lineArrow':
            self.DrawArea.bind('<B1-Motion>', self.lineArrow)
        elif name == 'color':
            # 默认颜色
            color = askcolor(self.fgcolor, title='颜色管理')
            self.fgcolor = color[1]  # 元组,第一个内容是RGB,第二个元素是十六进制的形式


    # 开始绘画的方法,如用画笔的时候,需要开始和停止绘制
    def startDraw(self, event):
        self.DrawArea.delete(self.lastDraw)
        if not self.firstDrawFlag:
            self.firstDrawFlag = True
            self.x, self.y = event.x, event.y # 跟随鼠标

    # 停止绘制
    def stopDraw(self, event):
        self.firstDrawFlag = False
        self.lastDraw = 0

    # 绘制矩形
    def rect(self, event):
        self.startDraw(event)
        # 绘制矩形的开始位置和结束位置坐标点,默认颜色
        self.lastDraw = self.DrawArea.create_rectangle(self.x, self.y, event.x, event.y, outline=self.fgcolor)

    # 画笔,画线
    def pen(self, event):
        self.startDraw(event)
        self.DrawArea.create_line(self.x, self.y, event.x,event.y,fill=self.fgcolor)
        self.x = event.x  # 画线的时候并不是直线,线弯曲的时候,弯曲的点即为下次绘画的起点
        self.y = event.y
    # 橡皮擦
    def eraser(self, event):
        self.startDraw(event)
        # 绘制橡皮擦的区域,颜色为背景颜色,也可以改为擦除的区域为线条
        self.DrawArea.create_rectangle(self.x, self.y, event.x, event.y, fill=self.bgcolor)

    # 画带箭头的直线
    def lineArrow(self, event):
        self.startDraw(event)
        self.lastDraw = self.DrawArea.create_line(self.x, self.y, event.x, event.y, arrow=LAST, fill=self.fgcolor)

    # 画直线
    def myline(self,event):
        self.startDraw(event)
        self.lastDraw = self.DrawArea.create_line(self.x, self.y, event.x, event.y, fill=self.fgcolor)

if __name__ == '__main__':
    root = Tk()
    root.geometry('1000x700+100+100')
    root.title('画板')
    # 通过类创建的实例对象放到root窗口上
    Application(master=root)
    # 窗口的消息循环,等待用户操作
    root.mainloop()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值