Qt双缓冲绘图简例

来源:互联网 发布:淘宝拍照专用手机 编辑:程序博客网 时间:2024/05/16 12:22

双缓冲绘图

如果想在涂鸦板上绘制矩形,并且可以动态地绘制这个矩形,也就是说可以用鼠标画出随意大小的矩形,那该怎么办呢?

我们先进行下面的三步,最后引出所谓的双缓冲绘图的概念。

第一步:

更改涂鸦程序的重绘函数。

void Dialog::paintEvent(QPaintEvent *)
{  
    QPainter painter(this);
    int x,y,w,h;
    x = lastPoint.x();
    y = lastPoint.y();
    w = endPoint.x() – x;
    h = endPoint.y() – y;
    painter.drawRect(x,y,w,h);
}

然后运行,效果如下。

这时我们已经可以拖出一个矩形了,但是这样直接在窗口上绘图,以前画的矩形是不能保存住的。所以我们下面加入画布,在画布上进行绘图。

第二步:

我们先在构造函数里将画布设置大点:pix = QPixmap(400,400);

然后更改函数,如下:

void Dialog::paintEvent(QPaintEvent *)
{  
    int x,y,w,h;
    x = lastPoint.x();
    y = lastPoint.y();
    w = endPoint.x() – x;
    h = endPoint.y() – y;
    QPainter pp(&pix);
    pp.drawRect(x,y,w,h);

    QPainter painter(this);
    painter.drawPixmap(0,0,pix);
}

这时运行程序,效果如下:

现在虽然能画出矩形,但是却出现了无数个矩形,这不是我们想要的结果,我们希望能像第一步那样绘制矩形,所以我们再加入一个临时画布。

第三步:

首先,我们在dialog.h中的private里添加变量声明:

QPixmap tempPix; //临时画布
bool isDrawing;   //标志是否正在绘图

然后在dialog.cpp中的构造函数里进行变量初始化:

isDrawing = false;

最后更改函数如下:

void Dialog::paintEvent(QPaintEvent *)
{  
    int x,y,w,h;
    x = lastPoint.x();
    y = lastPoint.y();
    w = endPoint.x() – x;
    h = endPoint.y() – y;

    QPainter painter(this);
    if(isDrawing)     //如果正在绘图
    {
        tempPix = pix;    //将以前pix中的内容复制到tempPix中,这样实现了交互绘图
        QPainter pp(&tempPix);
        pp.drawRect(x,y,w,h);
        painter.drawPixmap(0,0,tempPix); // 过程
    }
    else  // 最终显示结果
    {
        QPainter pp(&pix);
        pp.drawRect(x,y,w,h);
        painter.drawPixmap(0,0,pix);
    }
}

void Dialog::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton) //鼠标左键按下
    {
        lastPoint = event->pos();
        isDrawing = true;   //正在绘图
    }
}

void Dialog::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons()&Qt::LeftButton) //鼠标左键按下的同时移动鼠标
    {
        endPoint = event->pos();
        update();
    }
}
void Dialog::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton) //鼠标左键释放
    {
        endPoint = event->pos();
        isDrawing = false;    //结束绘图
        update();
    }
}

我们使用两个画布,就解决了绘制矩形等图形的问题。

其中tempPix = pix;一句代码很重要,就是它,才实现了消除那些多余的矩形。

我们已经看到,利用双缓冲绘图可以实现动态交互绘制。其实,Qt中所有部件进行绘制时,都是使用的双缓冲绘图。就算是第一步中我们没有用画布,Qt在进行自身绘制时也是使用的双缓冲绘图。

 

0 0