当前位置: 首页 > news >正文

C++ 作业 DAY5

作业

代码

Widtget.h

class Widget : public QWidget
{
    Q_OBJECT

public:
    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);      //生成小line
    line_attr_temp.line = line; //结构体line成员属性

    //置此,line_attr_temp所有属性获取完毕
    lines_attr.append(line_attr_temp);  //放到容器
    start = end;    //更新start
    update();
}

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)
    {
        //则删除刚刚 鼠标按下 时记录的start
        per_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();   //手动更新,触发绘图
    }
}

效果

颜色的随时调整

橡皮擦

撤销上一步

撤销完全

相关文章:

  • mybatisplus
  • 200W数据去重入库的几种方法及优缺点
  • RAGflow升级出错,把服务器灌满了
  • 1panel docker配置国内源
  • RAGflow采用docker-compose-continuous方式pull,把服务器充满了
  • 配置Spring Boot API接口超时时间(五种)
  • ArcGIS Pro 基于基站数据生成基站扇区地图
  • 在绘制原理图的时候,TYPE-C的CC引脚为什么要接下拉电阻?
  • ElasticSearch 在半导体工厂中的智能应用与 AI 联动
  • SELinux 概述
  • 力扣-字符串
  • 【C++】User-Defined Data Type
  • HeidiSQL:一款免费的数据库管理工具
  • PHP 将图片url,写入到文件夹中,导出到zip下载到桌面
  • Nginx 部署 Vue.js 项目指南:结合慈云数据服务器的实践
  • ZYNQ-PL学习实践(二)按键和定时器控制LED闪烁灯
  • AJAX 数据库
  • 2025年渗透测试面试题总结-字某跳动-渗透测试实习生(题目+回答)
  • K8s 1.27.1 实战系列(二)安装集群并初始化
  • Webshell 入侵与防御全攻略
  • 西安市做网站的公司/矿坛器材友情交换
  • 哈尔滨电子政务网站建设/写一篇软文1000字
  • 上海景泰建设有限公司网站/百度seo怎么提高排名
  • 中小企业网站建设示范平台/南宁网站运营优化平台
  • 做微商哪个网站有客源/优化大师 win10下载
  • 手机网站设置方法/优化关键词的公司