QGraphicsView的paintEvent双缓存绘画

前言:

不知道算不算QGraphicsView,基本没有使用到QGraphicsView的一些内置函数。个人觉得QGraphicsView还是不好理解。

使用步骤:

1.在所以需要的UI上增加一个QGraphicsView,并提升为超类,新建一个QGraphicsView类。

2.drawScene.h

#ifndef DRAWSCENE_H
#define DRAWSCENE_H

#include <QGraphicsView>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QKeyEvent>
#include <QPainter>
#include <QPixmap>
#include <QDebug>

class DrawScene : public QGraphicsView
{
    Q_OBJECT
public:
    DrawScene(QWidget  *parent = nullptr);
    ~DrawScene() override;
    //!  提供一个公共函数,设置pix界面大小,如没有设置,将设置成默认的值:1024,768
    void setDrawRectF(int x,int y);
private slots:
    void initSet();
protected:
    virtual void paintEvent(QPaintEvent *event) override;
    virtual void mousePressEvent(QMouseEvent *event) override;
    virtual void mouseMoveEvent(QMouseEvent *event) override;
    virtual void mouseReleaseEvent(QMouseEvent *event) override;
    virtual void keyPressEvent(QKeyEvent *event) override;



private:
    QPixmap pix;
    QPoint lasetPoint;
    QPoint movePoint;
    QPoint endPoint;
    QVector<QPointF> pointGroup;
    QPixmap tempPix;
    int rectX=1024;
    int rectY=768;
    bool isDrawing;
    bool isDoubleClick;
private:
    QGraphicsScene *scene;
    enum Action{
        Lines=0,    //铅笔画线
        Rects=1,    //画矩形
        Ellipses=2, //画椭圆
        Line=3,     //画直线
        Texts=4,    //文字
        AddTexts=5, //添加文字
        OpenPic=6,  //打开图片
        SavePic=7   //保存图片
    } drawAction;
};

#endif // DRAWSCENE_H

3.drawScene.cpp

#include "drawscene.h"

DrawScene::DrawScene(QWidget *parent)
    :QGraphicsView(parent)
{
    initSet();
}

DrawScene::~DrawScene()
{

}

void DrawScene::setDrawRectF(int x,int y)
{
    rectX=x;
    rectY=y;
}


void DrawScene::initSet()
{
    isDrawing = false;
    pix = QPixmap(rectX,rectY);
    pix.fill(Qt::gray);

}

void DrawScene::paintEvent(QPaintEvent *event)
{
    /// 双缓冲绘图,原理是在拖动过程中先把原来的图形复制到tempPix里面并在tempPix里面画,我们此时看到的就是在tempPix里的图形。只在鼠标释放的时候才在pix绘一次。


    QPainter painter(this->viewport());
    if (isDrawing)
    {
        tempPix = pix;
        QPainter pp(&tempPix);
        for (int i=0;i<pointGroup.size()-1;i++) {
            pp.drawLine(pointGroup.at(i),pointGroup.at(i+1));
        }
        painter.drawPixmap(0, 0, tempPix);
    }
    else
    {
        QPainter pp(&pix);
        for (int i=0;i<pointGroup.size()-1;i++) {
            pp.drawLine(pointGroup.at(i),pointGroup.at(i+1));
        }
        painter.drawPixmap(0, 0, pix);
        QVector<QPointF> nullGroup;
        pointGroup.swap(nullGroup);
    }

    QGraphicsView::paintEvent(event);
}

///**********************1.Press*********************************
void DrawScene::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        isDrawing = true;
        lasetPoint = event->pos();
        pointGroup.append(lasetPoint);
    }

    QGraphicsView::mousePressEvent(event);
}

///**********************2.Move*********************************
void DrawScene::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton)
    {
        movePoint=event->pos();
        pointGroup.append(movePoint);
        this->viewport()->update();
    }

    QGraphicsView::mouseMoveEvent(event);
}

///**********************3.Release*********************************
void DrawScene::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        endPoint = event->pos();
        pointGroup.append(movePoint);
        isDrawing = false;
        this->viewport()->update();
    }

    QGraphicsView::mouseReleaseEvent(event);
}

void DrawScene::keyPressEvent(QKeyEvent *event)
{
    QGraphicsView::keyPressEvent(event);
}

在过程中遇到的问题:

1.Qt中丰富的容器类---数组QVector、链表QLinkedList、映射表QMap、哈希表QHash

使用方法:

QVector<QPointF> pointGroup;
//! 添加
pointGroup.append(point);
//! 清空1:clear据说只清空内容,无法情况len
pointGroup.clear;
//! 清空2.新建一个QVector<QPointF>,用新的QVector<QPointF>代替。
QVector<QPointF> nullGroup;
pointGroup.swap(nullGroup);
tag(s): none
show comments · back · home
Edit with Markdown