菜单栏的功能都实现了,如果想添加工具栏可以用函数封装
代码放行使用
mainWindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QApplication> #include <QMenu> #include <QAction> #include <QMenuBar> #include <QDebug> #include <QMouseEvent> #include <QVector> #include <QPainter> #include <QPixmap> #include <QDialog> #include <QComboBox> #include <QFileDialog> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); enum Number{ One = 1, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten }; protected: void paintEvent(QPaintEvent *event)override; // 重绘事件 void resizeEvent(QResizeEvent *size)override; // 窗口大小变动事件 void mousePressEvent(QMouseEvent *event)override; // 鼠标点击事件 void mouseMoveEvent(QMouseEvent *event)override; // 鼠标移动事件 void mouseReleaseEvent(QMouseEvent *event)override; // 鼠标弹起事件 private: QMenu *menu; QAction *action1; QAction *action2; QAction *action3; QAction *action4; QAction *action5; QAction *action6; QAction *action7; QAction *action8; QAction *action9; QAction *actioncolor; QPixmap pixmap; QPixmap pix; QPixmap null; QPen pen; QComboBox *comboBox; QVector<QLine>line; // 直线 QVector<QLine>lines; // 铅笔 QVector<QVector<QLine>>vecline; // 记录铅笔移动的二维容器 QVector<QVector<QVector<QLine>>>myline; // 记录铅笔的三维容器 QVector<QRect>rect; // 椭圆 QVector<QRect>elli; // 矩形 QVector<int>vec; // 记录绘画的笔数 bool isMouse; Number num; Number tool; QApplication *t; // 退出事件循环的对象指针 public slots: void slotType(QAction *type); void slotColor(int color); }; #endif // MAINWINDOW_H
mainWindow.cpp
#include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { menu = menuBar()->addMenu(tr("绘图")); // 添加一个菜单栏 action1 = menu->addAction(tr("打开"),nullptr,nullptr,QKeySequence("Ctrl+O")); // 添加一个菜单 action2 = menu->addAction(tr("保存"),nullptr,nullptr,QKeySequence("Ctrl+S")); action3 = menu->addAction(tr("铅笔"),nullptr,nullptr,QKeySequence("Ctrl+1")); action4 = menu->addAction(tr("直线"),nullptr,nullptr,QKeySequence("Ctrl+2")); action5 = menu->addAction(tr("椭圆"),nullptr,nullptr,QKeySequence("Ctrl+3")); action6 = menu->addAction(tr("矩形"),nullptr,nullptr,QKeySequence("Ctrl+4")); actioncolor = menu->addAction(tr("颜色")); action7 = menu->addAction(tr("撤回"),nullptr,nullptr,QKeySequence("Ctrl+Z")); action8 = menu->addAction(tr("清除"),nullptr,nullptr,QKeySequence("Ctrl+D")); action9 = menu->addAction(tr("退出"),nullptr,nullptr,QKeySequence("Esc")); QActionGroup *actiongroup = new QActionGroup(this); actiongroup->addAction(action1); // 将动作存到Group中 actiongroup->addAction(action2); actiongroup->addAction(action3); actiongroup->addAction(action4); actiongroup->addAction(action5); actiongroup->addAction(action6); actiongroup->addAction(actioncolor); actiongroup->addAction(action7); actiongroup->addAction(action8); actiongroup->addAction(action9); connect(actiongroup,SIGNAL(triggered(QAction *)),this,SLOT(slotType(QAction *))); resize(this->width(),this->height()); pixmap = QPixmap(this->size()); pixmap.fill(Qt::white); pix = QPixmap(this->size()); pix.fill(Qt::white); null = QPixmap(this->size()); null.fill(Qt::white); isMouse = false; } MainWindow::~MainWindow() { } void MainWindow::paintEvent(QPaintEvent *event) { QPainter painter(this); if(isMouse){ pix = pixmap; // 得到上次绘画的东西 QPainter pain(&pix); pain.setPen(pen); if(num == Three){ pain.drawLine(lines.back()); lines.back().setP1(lines.back().p2()); // 更新首节点 pixmap = pix; // 将每次绘画的初始点和末尾点赋给pixmap } else if(num == Four && isMouse){ pain.drawLine(line.back().p1(),line.back().p2()); } else if(num == Five && isMouse){ pain.drawEllipse(elli.back()); } else if(num == Six && isMouse){ pain.drawRect(rect.back()); } } if(!isMouse){ pixmap = pix; QPainter pain(&pix); pain.setPen(pen); if(tool == Seven){ int linee=0,ellii=0,rectt=0; for(int i=0;i<vec.length();i++){ if(vec[i] == Three){ for(int i=0;i<myline.length();i++){ // 进入外层 2 for(int j=0;j<myline.at(i).length();j++){ // 进入 vecline 层 for(int k=0;k<myline.at(i).at(j).length();k++){ // 进入lines 层 pain.drawLine(myline.at(i).at(j).at(k)); } } } } else if(vec[i] == Four){ pain.drawLine(line.at(linee).p1(),line.at(linee).p2()); linee++; } else if(vec[i] == Five){ pain.drawEllipse(elli.at(ellii)); ellii++; } else if(vec[i] == Six){ pain.drawRect(rect.at(rectt)); rectt++; } } tool = Ten; } } painter.drawPixmap(0,0,pix); // painter.drawPixmap(610,0,pixmap); } void MainWindow::resizeEvent(QResizeEvent *size) // 当窗口大小变化更新画板 { this->resize(size->size()); pixmap = QPixmap(size->size()); pixmap.fill(Qt::white); pix = QPixmap(size->size()); pix.fill(Qt::white); null = QPixmap(size->size()); null.fill(Qt::white); } void MainWindow::mousePressEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton){ if(num == Three){ // 铅笔模式 QLine Lines(event->pos(),QPoint(0,0)); lines.append(Lines); // 记录点击的第一笔 vec.append(Three); // 添加那个模式点击的画笔 isMouse = true; // 开启绘画锁 } else if(num == Four){ // 直线模式 QLine Line(event->pos(),QPoint(0,0)); line.append(Line); vec.append(Four); isMouse = true; } else if(num == Five){ // 椭圆模式 QRect Elli(event->pos(),QPoint(0,0)); elli.append(Elli); vec.append(Five); isMouse = true; } else if(num == Six){ // 矩形模式 QRect Rect(event->pos(),QPoint(0,0)); rect.append(Rect); vec.append(Six); isMouse = true; } } else if(event->button() == Qt::RightButton){ // 右击菜单栏 menu->exec(cursor().pos()); } } void MainWindow::mouseMoveEvent(QMouseEvent *event) { if(!isMouse) return; if(event->buttons() == Qt::LeftButton){ if(num == Three){ // 铅笔移动模式 lines.back().setP2(event->pos()); // 设置点p2 的坐标为移动的坐标 vecline.append(lines); // 记录移动的两点 坐标 update(); } else if(num == Four){ // 直线移动模式 line.back().setP2(event->pos()); update(); } else if(num == Five){ // 椭圆移动模式 elli.back().setBottomRight(event->pos()); update(); } else if(num == Six){ // 矩形移动模式 rect.back().setBottomRight(event->pos()); update(); } } } void MainWindow::mouseReleaseEvent(QMouseEvent *event) { if(!isMouse) return; if(event->button() == Qt::LeftButton){ if(num == Three){ // 弹起铅笔模式 lines.back().setP2(event->pos()); // 更新一次释放点的坐标 myline.append(vecline); // 将上面移动的记录存到 三维容器中 QVector<QVector<QLine>>vecnullptr; vecline = vecnullptr; // 清空上一次 的vecline 记录的移动项 update(); } else if(num == Four){ // 弹起直线模式 line.back().setP2(event->pos()); update(); } else if(num == Five){ // 弹起椭圆模式 elli.back().setBottomRight(event->pos()); update(); } else if(num == Six){ // 弹起矩形模式 rect.back().setBottomRight(event->pos()); update(); } isMouse = false; // 关闭绘画锁 } } void MainWindow::slotType(QAction *type) // 触发点击的哪一个动作的槽函数 如果添加工具栏的话可以用函数封装下就行 { if(type == action1){ // 打开 QString filename = QFileDialog::getOpenFileName(this,tr("打开文件"),"/","Image(*.png);;Image(*.jpg)"); if(filename.isEmpty()) return; QPixmap pixopen(filename); QPainter p(&pix); p.drawPixmap(0,0,pixopen); update(); } else if(type == action2){ // 保存 QString filename = QFileDialog::getSaveFileName(this,tr("保存文件"),"image.png","Image(*.png);;Image(*.jpg)"); if(filename.isEmpty()) return; pix.save(filename); } else if(type == action3){ // 铅笔 num = Three; } else if(type == action4){ // 直线 num = Four; } else if(type == action5){ // 椭圆 num = Five; } else if(type == action6){ // 矩形 num = Six; } else if(type == actioncolor){ QDialog w; comboBox = new QComboBox(&w); QPixmap compix(16,16); QPainter painter(&compix); painter.fillRect(0,0,16,16,Qt::black); comboBox->addItem(QIcon(compix),tr("黑色")); painter.fillRect(0,0,16,16,Qt::white); comboBox->addItem(QIcon(compix),tr("白色")); painter.fillRect(0,0,16,16,Qt::red); comboBox->addItem(QIcon(compix),tr("红色")); painter.fillRect(0,0,16,16,Qt::blue); comboBox->addItem(QIcon(compix),tr("蓝色")); painter.fillRect(0,0,16,16,Qt::green); comboBox->addItem(QIcon(compix),tr("绿色")); painter.fillRect(0,0,16,16,Qt::yellow); comboBox->addItem(QIcon(compix),tr("黄色")); connect(comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(slotColor(int))); w.exec(); } else if(type == action7){ // 撤回 if(vec.isEmpty()) return; if(vec.back() == Three){ myline.pop_back(); } else if(vec.back() == Four){ line.pop_back(); } else if(vec.back() == Five){ elli.pop_back(); } else if(vec.back() == Six){ rect.pop_back(); } vec.pop_back(); pix = null; pixmap = null; tool = Seven; update(); } else if(type == action8){ // 清除 pix = null; pixmap = null; tool = Eight; update(); } else if(type == action9){ // 退出 t->quit(); } } void MainWindow::slotColor(int color) { switch (color) { case 0:pen.setColor(Qt::black); break; case 1:pen.setColor(Qt::white); break; case 2:pen.setColor(Qt::red); break; case 3:pen.setColor(Qt::blue); break; case 4:pen.setColor(Qt::green); break; case 5:pen.setColor(Qt::yellow);break; } }
main.cpp
#include "mainwindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
c/c++开发分享Qt 小画板地址:https://blog.csdn.net/qq_44698445/article/details/107347256
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/599039.html