Qt 小画板

5 篇文章 0 订阅
3 篇文章 0 订阅

菜单栏的功能都实现了,如果想添加工具栏可以用函数封装
代码放行使用
在这里插入图片描述
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();
}

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值