返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++之Qt5双缓冲机制案例教程
  • 952
分享到

C++之Qt5双缓冲机制案例教程

2024-04-02 19:04:59 952人浏览 泡泡鱼
摘要

1. 双缓冲机制 所谓双缓冲机制,是指在绘制控件时,首先将要绘制的内容绘制在一个图片中,再将图片一次性地绘制到控件上。 在早期的Qt版本中,若直接在控件上进行绘制工作,则在控件重绘时

1. 双缓冲机制

所谓双缓冲机制,是指在绘制控件时,首先将要绘制的内容绘制在一个图片中,再将图片一次性地绘制到控件上。

在早期的Qt版本中,若直接在控件上进行绘制工作,则在控件重绘时会产生闪烁的现象,控件重绘频繁时,闪烁尤为明显。

双缓冲机制可以有效地消除这种闪烁现象。自Qt 5版本之后,QWidget 控件已经能够自动处理闪烁的问题。

因此,在控件上直接绘图时,不用再操心显示的闪烁问题,但双缓冲机制在很多场合仍然有其用武之地。当所需绘制的内容较复杂并需要频繁刷新,或者每次只需要刷新整个控件的一小部分时,仍应尽量采用双缓冲机制。

2. 实例

2.1 介绍

实现一个简单的绘图工具,可以选择线形,线宽,颜色等基本要素

效果图

image-20210718215654198

2.2 部分关键代码讲解

构造函数


DrawWidget::DrawWidget(QWidget *parent) :
    QWidget(parent)
{
    setAutoFillBackground(true);    //对窗体背景色的设置
    setPalette(QPalette(Qt::red));
    pix =new QPixmap(size());      	//此QPixmap对象用来准备随时接收绘制的内容
    pix->fill(Qt::white);           //填充背景色为白色
    setMinimumSize(600,400);      	//设置绘制区窗体的最小尺寸
}

autoFillBackground

此属性保存小部件背景是否自动填充

如果启用,该属性将导致Qt在调用paint事件之前填充小部件的背景。使用的颜色是由小部件调色板中的QPalette::Window颜色角色定义的。

此外,windows总是填充QPalette::Window,除非设置了WA_OpaquePaintEvent或WA_NoSystemBackground属性。

如果小部件的父组件有一个静态背景渐变,则不能关闭这个属性(即设置为false)。


void DrawWidget::mousePressEvent(QMouseEvent *e)
{
    startPos = e->pos();
}

重定义鼠标按下事件 mousePressEvent(),在按下鼠标按键时,记录当前的鼠标位置值startPos。


重定义鼠标移动事件mouseMoveEvent(),鼠标移动事件在默认情况下,在鼠标按键被按下的同时拖曳鼠标时被触发。
QWidget的mouseTracking属性指示窗体是否追踪鼠标,默认为 false(不追踪),即在至少有一个鼠标按键被按下的前提下移动鼠标才触发mouseMoveEvent()事件,可以通过setMouseTracking(bool enable)方法对该属性值进行设置。如果设置为追踪,则无论鼠标按键是否被按下,只要鼠标移动,就会触发mouseMoveEvent()事件。在此事件处理函数中,完成向QPixmap对象中绘图的工作。具体代码如下:


void DrawWidget::mouseMoveEvent(QMouseEvent *e)
{
    QPainter *painter = new QPainter;

    QPen pen;
    pen.setStyle((Qt::PenStyle)style);
    pen.setWidth(weight);
    pen.setColor(color);

    painter->begin(pix);
    painter->setPen(pen);
    painter->drawLine(startPos,e->pos());
    painter->end();
    startPos =e->pos();
    update();
}

三个set就不说了,大家都明白,说下begin

bool QPainter::begin(QPaintDevice **device*)

开始绘制绘制设备,如果成功返回true;否则返回false,这里是在Pixmap中绘图

接下来是设置笔,然后看看drawLine函数

void QPainter::drawLine(const QPoint &p1, const QPoint &p2)

这是一个重载函数。从p1到p2画一条线。

然后设置当前的位置,e->pos()


看这个函数


void DrawWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.drawPixmap(QPoint(0,0),*pix);
}

这里是实现双缓冲区域的地方

在上一个函数里,我们不是直接在面版上画画,而且在Pixmap里面画画,在这里,我们调用drawPixmap()函数,将用于接收图形绘制的QPixmap对象绘制在绘制区窗体控件上,这样就实现了双缓冲机制


void DrawWidget::resizeEvent(QResizeEvent *event)
{
    if(height()>pix->height()||width()>pix->width())
    {
        QPixmap *newPix = new QPixmap(size());
        newPix->fill(Qt::white);
        QPainter p(newPix);
        p.drawPixmap(QPoint(0,0),*pix);
        pix = newPix;
    }
    QWidget::resizeEvent(event);
}

调整绘制区大小函数resizeEvent(),当窗体的大小发生改变时,效果看起来虽然像是绘制区大小改变了,但实际能够进行绘制的区域仍然没有改变。因为绘图的大小并没有改变,还是原来绘制区窗口的大小,所以在窗体尺寸变化时应及时调整用于绘制的QPixmap对象的大小

最后一句QWidget::resizeEvent(event);是为了完成其余的工作


接下来实现clear函数,

clear()函数完成绘制区的清除工作,只需调用一个新的、干净的QPixmap对象来代替pix,并调用update()函数重绘即可。


void DrawWidget::clear()
{
    QPixmap *clearPix =new QPixmap(size());
    clearPix->fill(Qt::white);
    pix = clearPix;
    update();
}

看看被我们忽视的fill()函数

void QPixmap::fill(const QColor &color = Qt::white)

用给定的颜色填充像素图。当pixmap被绘制时,这个函数的效果是未定义的。

上期已经说过的update()

更新小部件,除非禁用更新或隐藏小部件。

此函数不会导致立即重绘;相反,当Qt返回到主事件循环时,它会安排一个油漆事件进行处理。与调用repaint()相比,这允许Qt进行优化,以获得更快的速度和更少的闪烁。

到此这篇关于c++之Qt5双缓冲机制案例教程的文章就介绍到这了,更多相关C++之Qt5双缓冲机制内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++之Qt5双缓冲机制案例教程

本文链接: https://lsjlt.com/news/130838.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++之Qt5双缓冲机制案例教程
    1. 双缓冲机制 所谓双缓冲机制,是指在绘制控件时,首先将要绘制的内容绘制在一个图片中,再将图片一次性地绘制到控件上。 在早期的Qt版本中,若直接在控件上进行绘制工作,则在控件重绘时...
    99+
    2024-04-02
  • C++之Qt5双缓冲机制的示例分析
    这篇文章主要介绍了C++之Qt5双缓冲机制的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1. 双缓冲机制所谓双缓冲机制,是指在绘制控件时,首先将要绘制的内容绘制在一...
    99+
    2023-06-20
  • 详解Qt中的双缓冲机制与实例应用
    目录1、双缓冲机制2、实例效果图3、实例核心代码4、双缓冲具体实现代码1、双缓冲机制 所谓双缓冲机制,是指在绘制控件时,首先将要绘制的内容绘制在一个图片中,再将图片一次性地绘制到控件...
    99+
    2023-03-11
    Qt双缓冲机制 Qt双缓冲 Qt 缓冲
  • Java虚拟机类加载器之双亲委派机制模型案例
    1. 双亲委派模型是什么? 当某个类加载器需要加载某个.class字节码文件时,它首先把这个任务委托给它的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类...
    99+
    2024-04-02
  • C语言之函数返回值与参数传递案例教程
    C语言函数返回值与参数传递 一:参数传递 C语言的函数中必不可少的就是参数传递,可以采用传值和传指针两种方式。 1.传值的形式:只是将参数值的拷贝传给函数,并非参数本体如: in...
    99+
    2024-04-02
  • Java多线程之等待唤醒机制及案例代码演示
    生产者和消费者(等待唤醒机制) 等待唤醒机制常见方法代码演示等待唤醒机制(阻塞队列方式实现)额外扩展 等待唤醒机制 生产者和消费者是一个十分经典的多线程协作模式 举个小栗子来说明一下消费者...
    99+
    2023-10-25
    java 多线程 等待唤醒机制 thread Runnable notify wait
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作