widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QLine>
#include <QVector>
#include <QColor>
#include <QMouseEvent>
#include <QKeyEvent>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
// 线条信息结构体:包含线段、颜色和宽度
struct LineInfo {
QLine line; // 线段坐标
QColor color; // 线条颜色
int width; // 线条宽度
};
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
protected:
// 重写绘图事件
void paintEvent(QPaintEvent *event) override;
// 重写鼠标事件
void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
private slots:
// 槽函数:按钮点击事件
void on_pushButton_clicked(); // 打开调色板
void on_pushButton_2_clicked(); // 设置线宽为1
void on_pushButton_3_clicked(); // 设置线宽为5
void on_pushButton_4_clicked(); // 设置线宽为10
void on_pushButton_5_clicked();
private:
Ui::Widget *ui; // UI指针
QPoint start; // 鼠标按下时的起点坐标
QVector<LineInfo> lines;// 存储所有绘制的线条信息
QColor currentColor; // 当前画笔颜色
int currentWidth; // 当前画笔宽度
QString copy = "";
protected:
virtual void keyPressEvent(QKeyEvent *event) override;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QColorDialog>
#include <QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
, currentColor(Qt::black) // 初始化颜色为黑色
, currentWidth(1) // 初始化线宽为1
{
ui->setupUi(this);
setFocusPolicy(Qt::StrongFocus);
}
Widget::~Widget()
{
delete ui;
}
// 绘图事件处理函数
void Widget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event); // 避免未使用参数的警告
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); // 开启抗锯齿,使线条更平滑
// 遍历所有保存的线条信息
for (const LineInfo &lineInfo : lines) {
QPen pen(lineInfo.color, lineInfo.width); // 根据线条信息创建画笔
painter.setPen(pen);
painter.drawLine(lineInfo.line); // 绘制线段
}
}
// 鼠标移动事件处理函数(实时绘制)
void Widget::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) { // 确保左键按下
QPoint end = event->pos(); // 获取当前鼠标位置
QLine line(start, end); // 创建线段
// 保存当前线段信息(颜色、宽度)
LineInfo info;
info.line = line;
info.color = currentColor;
info.width = currentWidth;
lines.append(info); // 将线段添加到列表
start = end; // 更新起点为当前终点,实现连续绘制
update(); // 请求重绘,触发paintEvent
}
}
// 鼠标按下事件处理函数
void Widget::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
start = event->pos(); // 记录按下的起点坐标
}
}
// 鼠标释放事件处理函数(暂无特殊操作)
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event);
}
// 打开调色板选择颜色
void Widget::on_pushButton_clicked()
{
QColor color = QColorDialog::getColor(currentColor, this, "选择颜色");
if (color.isValid()) { // 用户选择了有效颜色
currentColor = color; // 更新当前颜色
}
}
// 设置线宽为1
void Widget::on_pushButton_2_clicked()
{
currentWidth = 1;
}
// 设置线宽为5
void Widget::on_pushButton_3_clicked()
{
currentWidth = 5;
}
// 设置线宽为10
void Widget::on_pushButton_4_clicked()
{
currentWidth = 10;
}
//橡皮擦
void Widget::on_pushButton_5_clicked()
{
// 获取当前窗口的背景色(智能获取背景色)
currentColor = palette().color(QPalette::Window);
// 设置橡皮擦宽度
currentWidth = 50;
}
//ctrl+z撤销
void Widget::keyPressEvent(QKeyEvent *event)
{
// 检查组合键:Ctrl+Z
if((event->modifiers() & Qt::ControlModifier) && (event->key() == Qt::Key_Z)){
qDebug() << "触发撤销操作";
if (!lines.isEmpty()) {
// 移除最后一条绘制记录
lines.removeLast();
// 请求界面重绘
update();
}
}
}