学会python——用python制作一个绘图板(python实例十九)

news2024/12/27 11:59:40

目录

1.认识Python

2.环境与工具

2.1 python环境

2.2 Visual Studio Code编译

3.制作一个绘图板

3.1 代码构思

3.2 代码实例

3.3 运行结果

4.总结


1.认识Python

Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。

Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字或标点符号,它具有比其他语言更有特色的语法结构。

 

2.环境与工具

2.1 python环境

在Windows上使用命令行窗口查看所安装的python版本

python --version

 

2.2 Visual Studio Code编译

Visual Studio Code是一款由微软开发且跨平台的免费源代码编辑器。该软件以扩展的方式支持语法高亮、代码自动补全、代码重构功能,并且内置了命令行工具和Git 版本控制系统。

3.制作一个绘图板

3.1 代码构思

使用tkinter模块,利用canvas控件进行绘制,然后使用画布控件,获取鼠标按键、移动、释放的操作。

3.2 代码实例

import tkinter as tk
from tkinter import colorchooser, filedialog, messagebox
from PIL import Image, ImageTk, ImageDraw
import os

class SimplePaint:
    def __init__(self, root):
        # 初始化
        self.root = root
        self.root.title("Simple Paint-简单绘图板-Zucker")
        self.root.geometry("800x600")
        
        # 创建画布
        self.canvas = tk.Canvas(root, bg="white", width=800, height=600)
        self.canvas.pack(fill=tk.BOTH, expand=True)
        
        # 初始化变量
        self.old_x = None
        self.old_y = None
        self.color = "black"
        self.eraser_on = False
        
        # 设置菜单和绑定事件
        self.setup_menu()
        self.setup_bindings()
        
    def setup_menu(self):
        # 设置菜单
        menu = tk.Menu(self.root)
        self.root.config(menu=menu)
        
        # 文件菜单
        file_menu = tk.Menu(menu, tearoff=0)
        menu.add_cascade(label="File", menu=file_menu)
        file_menu.add_command(label="Open", command=self.open_image)
        file_menu.add_command(label="Save", command=self.save_image)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=self.root.quit)
        
        # 编辑菜单
        edit_menu = tk.Menu(menu, tearoff=0)
        menu.add_cascade(label="Edit", menu=edit_menu)
        edit_menu.add_command(label="Clear All", command=self.clear_canvas)
        edit_menu.add_command(label="Erase", command=self.use_eraser)
        edit_menu.add_command(label="Insert Text", command=self.insert_text)
        edit_menu.add_command(label="Insert Image", command=self.insert_image)
        
        # 形状菜单
        shape_menu = tk.Menu(menu, tearoff=0)
        menu.add_cascade(label="Shapes", menu=shape_menu)
        shape_menu.add_command(label="Draw Line", command=self.draw_line)
        shape_menu.add_command(label="Draw Circle", command=self.draw_circle)
        
        # 颜色菜单
        color_menu = tk.Menu(menu, tearoff=0)
        menu.add_cascade(label="Color", menu=color_menu)
        color_menu.add_command(label="Choose Color", command=self.choose_color)
        
    def setup_bindings(self):
        # 绑定画布事件
        self.canvas.bind("<ButtonPress-1>", self.on_button_press)
        self.canvas.bind("<B1-Motion>", self.on_paint)
        self.canvas.bind("<ButtonRelease-1>", self.on_button_release)
        
    def choose_color(self):
        # 选择颜色
        self.eraser_on = False
        self.color = colorchooser.askcolor(color=self.color)[1]
        
    def clear_canvas(self):
        # 清除画布
        self.canvas.delete("all")
        
    def use_eraser(self):
        # 启用橡皮擦
        self.eraser_on = True
        
    def insert_text(self):
        # 插入文本
        self.eraser_on = False
        text = tk.simpledialog.askstring("Input", "Enter text to insert:")
        if text:
            self.canvas.create_text(400, 300, text=text, font=("Arial", 20), fill=self.color)
        
    def insert_image(self):
        # 插入图片
        self.eraser_on = False
        image_path = filedialog.askopenfilename()
        if image_path:
            img = Image.open(image_path)
            img = img.resize((200, 200), Image.ANTIALIAS)
            self.img = ImageTk.PhotoImage(img)
            self.canvas.create_image(400, 300, image=self.img, anchor=tk.CENTER)
        
    def draw_line(self):
        # 画线
        self.eraser_on = False
        self.draw_shape = "line"
        
    def draw_circle(self):
        # 画圆
        self.eraser_on = False
        self.draw_shape = "circle"
        
    def open_image(self):
        # 打开图片
        image_path = filedialog.askopenfilename()
        if image_path:
            img = Image.open(image_path)
            self.img = ImageTk.PhotoImage(img)
            self.canvas.create_image(0, 0, image=self.img, anchor=tk.NW)
        
    def save_image(self):
        # 保存图片
        file_path = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG files", "*.png"), ("All files", "*.*")])
        if file_path:
            # 保存画布内容为 PNG 图片
            self.canvas.postscript(file=file_path + '.eps')
            img = Image.open(file_path + '.eps')
            img.save(file_path, "png")
            os.remove(file_path + '.eps')
        
    def on_button_press(self, event):
        # 鼠标按下事件处理
        self.old_x = event.x
        self.old_y = event.y
        
    def on_paint(self, event):
        # 鼠标移动事件处理
        paint_color = self.color if not self.eraser_on else "white"
        if self.old_x and self.old_y:
            self.canvas.create_line(self.old_x, self.old_y, event.x, event.y, fill=paint_color, width=5, capstyle=tk.ROUND, smooth=tk.TRUE)
        self.old_x = event.x
        self.old_y = event.y
        
    def on_button_release(self, event):
        # 鼠标释放事件处理
        self.old_x = None
        self.old_y = None
        
if __name__ == "__main__":
    root = tk.Tk()
    app = SimplePaint(root)
    root.mainloop()

3.3 运行结果

4.总结

通过定义多个函数来执行命令,并进行可视化操作,你也试试吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1898482.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

并发、多线程和HTTP连接之间有什么关系?

一、并发的概念 并发是系统同时处理多个任务或事件的能力。在计算中&#xff0c;这意味着系统能够在同一时间段内处理多个任务&#xff0c;而不是严格按照顺序一个接一个地执行它们。并发提高了系统的效率和资源利用率&#xff0c;从而更好地满足用户的需求。在现代应用程序中&…

2-3 图像分类数据集

MNIST数据集是图像分类任务中广泛使用的数据集之一&#xff0c;但作为基准数据集过于简单&#xff0c;我们将使用类似但更复杂的Fashion-MNIST数据集。 %matplotlib inline import torch import torchvision # pytorch模型关于计算机视觉模型实现的一个库 from torch.utils i…

Ubuntu24.04LTS基础软件下载

librewolf: deb文件link 作用&#xff1a;访问github&#xff0c;无痕浏览&#xff0c;这个速度&#xff0c;不指望了 vscodium: 从deb安装&#xff0c;ubuntu sudo dpkg -i xxx.debpaste-image 插件替代 markdown wps: libreoffice: 替换USTC源 sudo nano /etc/apt/sourc…

昇思25天学习打卡营第8天|ResNet50迁移学习

一、迁移学习定义 迁移学习&#xff08;Transfer Learning&#xff09;&#xff1a;在一个任务上训练得到的模型包含的知识可以部分或全部地转移到另一个任务上。允许模型将从一个任务中学到的知识应用到另一个相关的任务中。适用于数据稀缺的情况&#xff0c;可减少对大量标记…

【hive】数据采样

参考https://hadoopsters.com/how-random-sampling-in-hive-works-and-how-to-use-it-7cdb975aa8e2&#xff0c;可以直接查看原文&#xff0c;下面只是对原文进行概括和实际性能测试。 1.distribute by sort by2.测试3.map端数据过滤优化采样 在说数据采样之前&#xff0c;需要…

聚集索引与非聚集索引的区别

1.从文件存储方式来区别 聚集索引是指表的索引和数据存储在一个文件中&#xff08;innodb&#xff09; 非聚集索引指表数据与表索引存储在两个文件中&#xff08;MyISAM&#xff09; 2.从文件的检索方式来区别 聚集索引的data存在叶子节点 非聚集索引叶子节点存储的事data的…

三叶青图像识别研究简概

三叶青图像识别研究总概 文章目录 前言一、整体目录介绍二、前期安排三、构建图像分类数据集四、模型训练准备五、迁移学习模型六、在测试集上评估模型精度七、可解释性分析、显著性分析八、图像分类部署九、树莓派部署十、相关补充总结 前言 本系列文章为近期所做项目研究而作…

Java并发编程知识整理笔记

目录 ​1. 什么是线程和进程&#xff1f; 线程与进程有什么区别&#xff1f; 那什么是上下文切换&#xff1f; 进程间怎么通信&#xff1f; 什么是用户线程和守护线程&#xff1f; 2. 并行和并发的区别&#xff1f; 3. 创建线程的几种方式&#xff1f; Runnable接口和C…

基于aardio web.view2库和python playwright包的内嵌浏览器自动化操作

通过cdp协议可以实现playwright操控webview。 新建Python窗口工程 修改pip.aardio 修改pip.aardio&#xff0c;并执行&#xff0c;安装playwright。 //安装模块 import process.python.pip; //process.python.path "python.exe";/* 安装模块。 参数可以用一个字…

深度学习每周学习总结N3(文本分类实战:基本分类(熟悉流程)、textCNN分类(通用模型)、Bert分类(模型进阶))

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 目录 0. 总结&#xff1a;1. 前期准备环境安装 2. 文本分类基本流程a. 加载数据b.构建词典c.生成数据批次和迭代器d.定义模型及实例e. 定义…

C++ 仿QT信号槽二

// 实现原理 // 每个signal映射到bitset位&#xff0c;全集 // 每个slot做为signal的bitset子集 // signal全集触发&#xff0c;标志位有效 // flip将触发事件队列前置 // slot检测智能指针全集触发的标志位&#xff0c;主动运行子集绑定的函数 // 下一帧对bitset全集进行触发清…

玩转内网穿透详细教程,收藏这一篇就够了

小朋友&#xff0c;你是否有过以下这些烦恼&#xff1f; 当你在外地&#xff0c;苦于无法拿到存储在家里的资料&#xff1b; 当你在玩游戏的时候&#xff0c;苦于无法和朋友直接联机&#xff1b; 当你在家里&#xff0c;苦于无法通过自己的电脑连上公司电脑远程办公&#xf…

论文导读 | 综述:大模型与推荐系统

最近&#xff0c;预训练语言模型&#xff08;PLM&#xff09;在自然语言处理领域取得了巨大成功&#xff0c;并逐渐引入推荐系统领域。本篇推文介绍了最近的两篇预训练语言模型和推荐系统结合的综述&#xff1a; [1] Pre-train, Prompt, and Recommendation: A Comprehensive …

Django学习第五天

启动项目命令 python manage.py runserver 图像验证码生成随机字母或者数字 import random from PIL import Image, ImageDraw, ImageFont, ImageFilterdef check_code(width120, height40, char_length5, font_fileZixunHappyBold.ttf, font_size28):code []img Image.new…

《后端程序猿 · Caffeine 本地缓存》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻一周&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

4、SSD主控

简述 主控是个片上系统&#xff0c;由硬件和固件组成一个功能完整的系统&#xff1b;上文所述的FTL就属于主控的固件范畴。主控闪存构成了整个SSD&#xff0c;在闪存确定的情况下&#xff0c;主控就反映了各家SSD的差异。实时上各家SSD的差异也主要反应在主控上&#xff0c;毕…

TCP和IP数据包结构

一、问题引入 一般我们在谈上网速度的时候&#xff0c;专业上用带宽来描述&#xff0c;其实无论说网速或者带宽都是不准确的&#xff0c;呵呵。比如&#xff1a;1兆&#xff0c;512K……有些在学校的学生&#xff0c;也许会有疑问&#xff0c;明明我的业务是1M&#xff0c;为…

打开浏览器控制台,点击应用,浏览器崩溃

调试的时候&#xff0c;打开控制台&#xff0c;点击 “应用” 立马浏览器奔溃&#xff0c;但是点击别的没问题 调查发现是因为manifest.json这个文件引起的 manifest.json 最主要的原因是因为没有设置这个sizes字段 Google浏览器更新大概到126之后的版本会有问题&#xff0c;之…

vuepress使用简介及个人博客搭建

目录 一、介绍二、环境准备三、安装运行vuepress四、目录结构五、配置文件六、导航栏配置七、导航栏logo八、浏览器图标九、侧边栏配置十、添加 Git 仓库和编辑链接十一、部署到GitHub十二、搭建成功 一、介绍 VuePress 是 Vuejs 官方提供的一个是Vue驱动的静态网站生成器&…

10.09面试题目记录

艾融软件 - 线上面试题 排序算法的时间复杂度 O(n^2&#xff09;&#xff1a;冒泡&#xff0c;选择&#xff0c;插入 O(logn&#xff09;&#xff1a;折半插入排序 O(nlogn)&#xff1a;希尔&#xff0c;归并&#xff0c;快速&#xff0c;堆 O(nk)&#xff1a;桶&#xff0c;…