C++ 作业 DAY5

作业

代码

Widtget.h

class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;/************************ 起始终止坐标 ************************/QPoint end;QPoint start;QVector<QPoint> per_start_list;   //容器 记录每一次鼠标按下的start/************************ 画笔相关 ************************/QPainter painter;   //绘画QPen pen;           //画笔/************************ 移动轨迹line ************************/struct line_attr{QLine line;                 //线长QColor color = Qt::black;   //颜色int width = 1;              //粗细}line_attr_temp;    //line属性bool rubber_in_use=0;               //橡皮擦标志位:0未用 1使用QVector<line_attr> lines_attr;      //容器 记录每一个move时 line的属性protected:virtual void paintEvent(QPaintEvent *event) override;virtual void mouseMoveEvent(QMouseEvent *event) override;virtual void mousePressEvent(QMouseEvent *event) override;virtual void mouseReleaseEvent(QMouseEvent *event) override;virtual void keyPressEvent(QKeyEvent *event) override;
private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();void on_pushButton_3_clicked();void on_pushButton_4_clicked();void on_pushButton_5_clicked();
};
#endif // WIDGET_H

Widget.cpp

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}/**************** 绘画逻辑 ****************/
void Widget::paintEvent(QPaintEvent *event)
{painter.begin(this);for(auto perline:lines_attr){pen.setColor(perline.color);pen.setWidth(perline.width);painter.setPen(pen);painter.drawLine(perline.line);}painter.end();
}/**************** 鼠标逻辑 ****************/
void Widget::mouseMoveEvent(QMouseEvent *event)
{end = event->pos();         //获取鼠标最后位置QLine line(start,end);      //生成小lineline_attr_temp.line = line; //结构体line成员属性//置此,line_attr_temp所有属性获取完毕lines_attr.append(line_attr_temp);  //放到容器start = end;    //更新startupdate();
}void Widget::mousePressEvent(QMouseEvent *event)
{start = event->pos();per_start_list << start;
}void Widget::mouseReleaseEvent(QMouseEvent *event)
{end = event->pos();// 检查:如果鼠标没有移动if(per_start_list.last()==end){//则删除刚刚 鼠标按下 时记录的startper_start_list.removeLast();}
}
/*
错误现象:画线后,空点一次,再使用撤销,会出现段错误
错误原因:空点时,起始坐标start 放入容器中,但是没有产生线段,撤销时的判断 "" 永远无法达到,会一直删除最后一个,直到段错误
错误解决:如果空点,即 "start==end" 则不写入容器
特殊情况?如果没有空点,但是移动后 "start==end" ????
*//**************** 画笔颜色 ****************/
// 打开调色板
void Widget::on_pushButton_clicked()
{line_attr_temp.color = QColorDialog::getColor(Qt::black,this,"选择颜色");
}/**************** 画笔粗细 ****************/
void Widget::on_pushButton_2_clicked()
{line_attr_temp.width=1;
}void Widget::on_pushButton_3_clicked()
{line_attr_temp.width=5;
}void Widget::on_pushButton_4_clicked()
{line_attr_temp.width=10;
}/**************** 橡皮擦逻辑 ****************/
void Widget::on_pushButton_5_clicked()
{//备份当前画笔属性static struct line_attr line_attr_temp_backup = line_attr_temp;//切换橡皮擦状态rubber_in_use=!rubber_in_use;if(rubber_in_use){//更改橡皮擦文本ui->pushButton_5->setText("使用中");//设置橡皮擦画笔line_attr_temp.color = this->palette().color(QPalette::Background);qDebug() << "北京颜色" << this->palette().color(QPalette::Background);line_attr_temp.width = 30;//其他操作ui->pushButton->setEnabled(0);      //使调色板失效ui->pushButton_2->setEnabled(0);    //使画笔粗细失效ui->pushButton_3->setEnabled(0);ui->pushButton_4->setEnabled(0);}else{//按钮文本描述ui->pushButton_5->setText("Erasers");//恢复画笔属性line_attr_temp=line_attr_temp_backup;//其他操作ui->pushButton->setEnabled(1);ui->pushButton_2->setEnabled(1);ui->pushButton_3->setEnabled(1);ui->pushButton_4->setEnabled(1);}
}/**************** Ctrl + Z ****************/
void Widget::keyPressEvent(QKeyEvent *event)
{if(event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Z){qDebug() << "Ctrl + Z 按下";// 如果容器不为空if (!per_start_list.isEmpty()){// 则允许遍历撤销while(lines_attr.last().line.p1() != per_start_list.last()){qDebug() << "成功进入p1()";// 则删除最后一个元素lines_attr.removeLast();}lines_attr.removeLast();per_start_list.removeLast();}update();   //手动更新,触发绘图}
}

效果

颜色的随时调整

橡皮擦

撤销上一步

撤销完全

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

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

相关文章

Selenium 中 ActionChains 支持的鼠标和键盘操作设置及最佳实践

Selenium 中 ActionChains 支持的鼠标和键盘操作设置及最佳实践 一、引言 在使用 Selenium 进行自动化测试时&#xff0c;ActionChains 类提供了强大的功能&#xff0c;用于模拟鼠标和键盘的各种操作。通过 ActionChains&#xff0c;可以实现复杂的用户交互&#xff0c;如鼠标…

前端面试技术性场景题

87.场景面试之大数运算&#xff1a;超过js中number最大值的数怎么处理 在 JavaScript 中&#xff0c;Number.MAX_SAFE_INTEGER&#xff08;即 2^53 - 1&#xff0c;即 9007199254740991&#xff09;是能被安全表示的最大整数。超过此值时&#xff0c;普通的 Number 类型会出现…

【js逆向】iwencai国内某金融网站实战

地址&#xff1a;aHR0cHM6Ly93d3cuaXdlbmNhaS5jb20vdW5pZmllZHdhcC9ob21lL2luZGV4 在搜索框中随便输入关键词 查看请求标头&#xff0c;请求头中有一个特殊的 Hexin-V,它是加密过的&#xff1b;响应数据包中全是明文。搞清楚Hexin-V的值是怎么生成的&#xff0c;这个值和cooki…

ES Module 的 import 导入和 import () 动态导入

ES Module 的 import 导入和 import () 动态导入介绍 一、ES Module 简介 ES Module 是 JavaScript 官方提供的标准化模块系统&#xff0c;它的出现解决了长期以来 JavaScript 在模块管理方面的混乱局面。通过 ES Module&#xff0c;开发者可以更加方便地组织和复用代码&…

使用Node.js从零搭建DeepSeek本地部署(Express框架、Ollama)

目录 1.安装Node.js和npm2.初始化项目3.安装Ollama4.下载DeepSeek模型5.创建Node.js服务器6.运行服务器7.Web UI对话-Chrome插件-Page Assist 1.安装Node.js和npm 首先确保我们机器上已经安装了Node.js和npm。如果未安装&#xff0c;可以通过以下链接下载并安装适合我们操作系…

BUUCTF——[GYCTF2020]FlaskApp1 SSTI模板注入/PIN学习

目录 一、网页功能探索 二、SSTI注入 三、方法一 四、方法二 使用PIN码 &#xff08;1&#xff09;服务器运行flask登录所需的用户名 &#xff08;2&#xff09;modename &#xff08;3&#xff09;flask库下app.py的绝对路径 &#xff08;4&#xff09;当前网络的mac地…

Java基础关键_018_集合(二)

目 录 一、泛型 ※ 1.说明 2.实例 3.擦除与补偿 4.泛型的定义 &#xff08;1&#xff09;类定义 &#xff08;2&#xff09;静态方法定义 &#xff08;3&#xff09;接口定义 5.通配符 &#xff08;1&#xff09;无限定 &#xff08;2&#xff09;上限 &#xff…

FPGA学习篇——Verilog学习3(关键字+注释方法+程序基本框架)

1 Verilog常用关键字 大概知道以下哪些是关键字就好&#xff0c;如何使用还是得在编写代码中来学习。 2 Verilog注释方法 Verilog有两种注释方式&#xff1a; 2.1 “ // ” 单行。 2.2 “ /* ... */ ” 可扩展多行。 3 Verilog程序基本框架 Verilog 的基本设计单元是“…

FPGA之USB通信实战:基于FX2芯片的Slave FIFO回环测试详解

FPGA之Usb数据传输 Usb 通信 你也许会有疑问&#xff0c;明明有这么多通信方式和数据传输&#xff08;SPI、I2C、UART、以太网&#xff09;为什么偏偏使用USB呢? 原因有很多&#xff0c;如下&#xff1a; 1. 高速数据传输能力 高带宽&#xff1a;USB接口提供了较高的数据传…

深入理解与配置 Nginx TCP 日志输出

一、背景介绍 在现代网络架构中&#xff0c;Nginx 作为一款高性能的 Web 服务器和反向代理服务器&#xff0c;广泛应用于各种场景。除了对 HTTP/HTTPS 协议的出色支持&#xff0c;Nginx 从 1.9.0 版本开始引入了对 TCP 和 UDP 协议的代理功能&#xff0c;这使得它在处理数据库…

【大模型安全】安全解决方案

【大模型安全】安全解决方案 1.技术层面2.数据层面数据收集阶段训练阶段模型推理阶段 1.技术层面 在使用大语言模型时&#xff0c;通常有几种选择&#xff1a;一种是采用封装好的大语言模型SaaS云服务&#xff1b;另一种是在公有云上部署自有的大语言模型&#xff0c;并通过权…

python中httpx库的详细使用及案例

文章目录 1. 安装 httpx2. 同步请求3. 异步请求4. 高级功能5. 错误处理6. 配置客户端7. 结合 Beautiful Soup 使用8. 示例:抓取并解析网页9. 注意事项httpx 是一个现代化的 Python HTTP 客户端库,支持同步和异步请求,功能强大且易于使用。它比 requests 更高效,支持 HTTP/2…

OpenCV计算摄影学(19)非真实感渲染(Non-Photorealistic Rendering, NPR)

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 非真实感渲染&#xff08;Non-Photorealistic Rendering, NPR&#xff09;是一种计算机图形学技术&#xff0c;旨在生成具有艺术风格或其他非现实…

微信小程序点击按钮,将图片下载到本地

前言&#xff1a; 最近在公司完成一个小程序的时候需要实现一个功能&#xff1a;点击按钮获取用户相册权限&#xff0c;将图片下载到用户本地相册&#xff0c;经过了好几次的尝试最终算是实现了。将总结的经验在这里分享给小伙伴们。 实现方式&#xff1a; //.wxml文件 <…

数据仓库为什么要分层

数据仓库分层架构是数据仓库设计中的一个重要概念&#xff0c;其主要目的是为了更好地组织和管理数据&#xff0c;提高数据仓库的可维护性、可扩展性和性能。分层架构将数据仓库划分为多个层次&#xff0c;每个层次都有其特定的职责和功能。以下是数据仓库分层的主要原因和好处…

selenium库

一、什么是selenium库&#xff1f; selenim是一个用于Web应用程序自动化测试工具&#xff0c;selenium测试直接运行在浏览器中 像真正的用户在操作一样&#xff0c;驱动浏览器执行特定的动作&#xff0c;如点击&#xff0c;下拉等操作 二、selenium在爬虫中的应用 获取动态…

python从入门到精通(二十四):python爬虫实现登录功能

这里写目录标题 requests实现登录功能selenium实现登录功能 requests实现登录功能 使用 requests 库结合会话&#xff08;Session&#xff09;来尝试登录。不过豆瓣有反爬虫机制&#xff0c;这种方式可能会受到验证码等因素的限制 import requests import re# 豆瓣登录页面 l…

十七、从0开始卷出一个新项目之瑞萨RZN2L定时器(GPT)+DMA生成PWM的运动控制

一、概述 嵌入式科普(34)通过对比看透DMA的本质 分享瑞萨RZN2L使用DMA生成PWM的运动控制的例程源码 rzn2l必要的外设资源&#xff1a; rzn2l拥有32-bit timer General PWM Timer (GPT) with 18 channels CPU、GPT最高频率400Mhz DMAC0 and DMAC1 8 channels 8 channels 还…

MR的环形缓冲区(底层)

MapReduce的大致流程&#xff1a; 1、HDFS读取数据&#xff1b; 2、按照规则进行分片&#xff0c;形成若干个spilt&#xff1b; 3、进行Map 4、打上分区标签&#xff08;patition&#xff09; 5、数据入环形缓冲区&#xff08;KVbuffer&#xff09; 6、原地排序&#xff…

解锁STM32外设:开启嵌入式开发新世界

✨✨✨这里是小韩学长yyds的BLOG(喜欢作者的点个关注吧) ✨✨✨想要了解更多内容可以访问我的主页 小韩学长yyds-CSDN博客 目录 探索 STM32 强大的外设家族 初窥门径&#xff1a;STM32 外设开发基础 开发方式与工具 外设配置基础步骤 深入剖析&#xff1a;常见外设应用实例…