欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Qt 小画板

程序员文章站 2022-03-23 15:41:31
菜单栏的功能都实现了,如果想添加工具栏可以用函数封装代码放行使用mainWindow.h#ifndef MAINWINDOW_H#define MAINWINDOW_H#include #include #include #include #include #include #include...

菜单栏的功能都实现了,如果想添加工具栏可以用函数封装
代码放行使用
Qt 小画板
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();
}

本文地址:https://blog.csdn.net/qq_44698445/article/details/107347256