實現一個繪圖工具,具備以下功能:
-
鼠標繪制線條。
-
實時調整線條顏色和粗細。
-
橡皮擦功能,覆蓋繪制內容。
-
撤銷功能,ctrl + z 快捷鍵撤銷最后一筆
程序代碼:
<1> Widget.h:
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
#include <QDebug>
#include <QMouseEvent>
#include <QLine>
#include <QVector>
#include <QColorDialog>
#include <QPair>
#include <QKeyEvent>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;QPoint start;QPoint end;QVector<QVector<QPair<QLine, QPair<QColor, int>>>> strokes; // 存儲每一筆的所有線段QVector<QPair<QLine, QPair<QColor, int>>> currentStroke; // 當前正在繪制的一筆QColor currentColor = Qt::black; // 當前顏色int currentWidth = 1; // 當前線條粗細bool isEraserMode = false; // 是否為橡皮擦模式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(); // 1mmvoid on_pushButton_3_clicked(); // 5mmvoid on_pushButton_4_clicked(); // 10mmvoid on_pushButton_6_clicked(); // 20mmvoid on_pushButton_5_clicked(); // 橡皮擦
};
#endif // WIDGET_H
<2> Widget.cpp:
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);setPalette(QPalette(Qt::white)); // 設置窗口背景色為白色setAutoFillBackground(true); // 自動填充背景
}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);QPen pen;// 遍歷所有筆觸,繪制每一筆for (const auto &stroke : strokes) {for (const auto &linePair : stroke) {pen.setColor(linePair.second.first); // 設置線條顏色pen.setWidth(linePair.second.second); // 設置線條粗細painter.setPen(pen);painter.drawLine(linePair.first); // 繪制線條}}// 繪制當前正在繪制的一筆for (const auto &linePair : currentStroke) {pen.setColor(linePair.second.first); // 設置線條顏色pen.setWidth(linePair.second.second); // 設置線條粗細painter.setPen(pen);painter.drawLine(linePair.first); // 繪制線條}
}void Widget::mouseMoveEvent(QMouseEvent *event)
{if (event->buttons() & Qt::LeftButton) {end = event->pos();QLine line(start, end);// 如果是橡皮擦模式,使用背景色繪制if (isEraserMode) {QColor backgroundColor = palette().color(QPalette::Window); // 獲取窗口背景色currentStroke << qMakePair(line, qMakePair(backgroundColor, currentWidth)); // 使用背景色覆蓋} else {currentStroke << qMakePair(line, qMakePair(currentColor, currentWidth)); // 正常繪制}start = end;update(); // 觸發重繪}
}void Widget::mousePressEvent(QMouseEvent *event)
{if (event->button() == Qt::LeftButton) {start = event->pos(); // 記錄起點currentStroke.clear(); // 開始新的一筆}
}void Widget::mouseReleaseEvent(QMouseEvent *event)
{if (event->button() == Qt::LeftButton) {end = event->pos();QLine line(start, end);// 如果是橡皮擦模式,使用背景色繪制if (isEraserMode) {QColor backgroundColor = palette().color(QPalette::Window); // 獲取窗口背景色currentStroke << qMakePair(line, qMakePair(backgroundColor, currentWidth)); // 使用背景色覆蓋} else {currentStroke << qMakePair(line, qMakePair(currentColor, currentWidth)); // 正常繪制}strokes << currentStroke; // 將當前一筆添加到所有筆觸中currentStroke.clear(); // 清空當前一筆update(); // 觸發重繪}
}// 鍵盤事件處理
void Widget::keyPressEvent(QKeyEvent *event)
{// 檢測 Ctrl + Z 按鍵組合if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Z) {if (!strokes.isEmpty()) {strokes.removeLast(); // 移除最后一整筆update(); // 觸發重繪}}
}// 打開調色板
void Widget::on_pushButton_clicked()
{currentColor = QColorDialog::getColor(currentColor, this, "選擇顏色");
}void Widget::on_pushButton_2_clicked()
{currentWidth = 1; // 設置線條粗細為 1
}void Widget::on_pushButton_3_clicked()
{currentWidth = 5; // 設置線條粗細為 5
}void Widget::on_pushButton_4_clicked()
{currentWidth = 10; // 設置線條粗細為 10
}void Widget::on_pushButton_6_clicked()
{currentWidth = 20; // 設置線條粗細為 20
}// 切換橡皮擦模式
void Widget::on_pushButton_5_clicked()
{isEraserMode = !isEraserMode; // 切換橡皮擦模式if (isEraserMode) {ui->pushButton_5->setText("繪圖模式"); // 更新按鈕文本} else {ui->pushButton_5->setText("橡皮擦"); // 更新按鈕文本}
}
<3> main.cpp:
#include "widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}