QT update和repaint的区别

简介: void QWidget::repaint ( int x, int y, int w, int h, bool erase = TRUE ) [槽] 通过立即调用paintEvent()来直接重新绘制窗口部件,如果erase为真,Qt在paintEvent()调用之前擦除区域(x,y,w,h)。

void QWidget::repaint ( int x, int y, int w, int h, bool erase = TRUE ) [槽]

通过立即调用paintEvent()来直接重新绘制窗口部件,如果erase为真,Qt在paintEvent()调用之前擦除区域(x,y,w,h)。 

如果w是负数,它被width()-x替换,并且如果h是负数,它被height()-y替换。 如果你需要立即重新绘制,建议使用repaint(),

比如在动画期间。在绝大多数情况下,update()更好,因为它允许Qt来优化速度并且防止闪烁。 

警告:如果你在一个函数中调用repaint(),而它自己又被paintEvent()调用,你也许会看到无线循环。

update()函数从来不会产生循环。

void QWidget::update () [槽]

更新窗口部件,当Qt回到主事件中时,它规划了所要处理的绘制事件。这样允许Qt进行优化从而得到比调用repaint()更快的速度和

更少的闪烁。 几次调用update()的结果通常仅仅是一次paintEvent()调用。 Qt通常在paintEvent()调用之前擦除这个窗口部件的

区域,仅仅只有在WRepaintNoErase窗口部件标记被设置的时候才不会。

在这区别中关键点是:repaint()是立即调用paintEvent(),而update()是几次执行才调用一次paintEvent()。

这样update()会造成这样的结果:paintEvent()中的任务没有执行完,就又被update().paintEvent()中被积压的任务越来越多。

程序例子:

(1)问题出现时候的情况(10毫秒每次,用update()。paintEvent()积累了很多处理任务):

#include<QPainter>

#include<QDebug>

#include<QMessageBox>

#include "mainwindow.h"

#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :

    QMainWindow(parent),

    ui(new Ui::MainWindow)

{

    ui->setupUi(this);

    this->showMaximized();

    i = 0;

    realWidth = this->width();

    realHeight = this->height();

    pixmap = QPixmap(realWidth,realHeight);

    connect(this,SIGNAL(haveData(QPoint)),this,SLOT(getPointAndDraw(QPoint)));

    connect(&timer,SIGNAL(timeout()),this,SLOT(getPoint()));

    timer.start(10);

}

MainWindow::~MainWindow()

{

    delete ui;

}

void MainWindow::getPoint()

{

    if(i < realWidth)

    {

        point = QPoint(i,(uint(qrand())) % realHeight);

        i++;

    }

    else

    {

        i = i % realWidth;

        point = QPoint(i,(uint(qrand())) % realHeight);

        i++;

    }

    emit haveData(point);

}

void MainWindow::getPointAndDraw(QPoint point)

{

    index = point.x();

    QPainter painter(&pixmap);

    painter.setPen(Qt::green);

    painter.drawLine(lastPoint,point);

    painter.setPen(Qt::black);

    painter.setBrush(Qt::red);

    painter.drawRect(index+1,0,5,realHeight);

    if(point.x() < realWidth-1)

        lastPoint = point;

    else

        lastPoint = QPoint(0,0);

  update();

  // this->repaint(index-1,0,5,realHeight);

}

void MainWindow::paintEvent(QPaintEvent *e)

{

    //return ;

    QPainter painter(this);

    QRect target1(0, 0, realWidth, realHeight/5);

    QRect target2(0, realHeight/5, realWidth, realHeight/5);

    QRect target3(0, 2*realHeight/5, realWidth, realHeight/5);

    QRect target4(0, 3*realHeight/5, realWidth, realHeight/5);

    QRect target5(0, 4*realHeight/5, realWidth, realHeight/5);

    QRect source(0, 0, realWidth, realHeight);

    painter.drawPixmap(target1,pixmap,source);

    painter.drawPixmap(target2,pixmap,source);

    painter.drawPixmap(target3,pixmap,source);

    painter.drawPixmap(target4,pixmap,source);

    painter.drawPixmap(target5,pixmap,source);

}

void MainWindow::resizeEvent(QResizeEvent *e)

{

    realWidth = this->width();

    realHeight = this->height();

}

void MainWindow::changeEvent(QEvent *e)

{

    QMainWindow::changeEvent(e);

    switch (e->type()) {

    case QEvent::LanguageChange:

        ui->retranslateUi(this);

        break;

    default:

        break;

    }

}

(2)每隔1000毫秒刷新一次,用update().一秒种有足够的时间处理paintEvent(),无积累。

#include<QPainter>

#include<QDebug>

#include<QMessageBox>

#include "mainwindow.h"

#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :

    QMainWindow(parent),

    ui(new Ui::MainWindow)

{

    ui->setupUi(this);

    this->showMaximized();

    i = 0;

    realWidth = this->width();

    realHeight = this->height();

    pixmap = QPixmap(realWidth,realHeight);

    connect(this,SIGNAL(haveData(QPoint)),this,SLOT(getPointAndDraw(QPoint)));

    connect(&timer,SIGNAL(timeout()),this,SLOT(getPoint()));

    timer.start(1000);

}

MainWindow::~MainWindow()

{

    delete ui;

}

void MainWindow::getPoint()

{

    if(i < realWidth)

    {

        point = QPoint(i,(uint(qrand())) % realHeight);

        i++;

    }

    else

    {

        i = i % realWidth;

        point = QPoint(i,(uint(qrand())) % realHeight);

        i++;

    }

    emit haveData(point);

}

void MainWindow::getPointAndDraw(QPoint point)

{

    index = point.x();

    QPainter painter(&pixmap);

    painter.setPen(Qt::green);

    painter.drawLine(lastPoint,point);

    painter.setPen(Qt::black);

    painter.setBrush(Qt::red);

    painter.drawRect(index+1,0,5,realHeight);

    if(point.x() < realWidth-1)

        lastPoint = point;

    else

        lastPoint = QPoint(0,0);

 update();

  // this->repaint(index-1,0,5,realHeight);

}

void MainWindow::paintEvent(QPaintEvent *e)

{

    //return ;

    QPainter painter(this);

    QRect target1(0, 0, realWidth, realHeight/5);

    QRect target2(0, realHeight/5, realWidth, realHeight/5);

    QRect target3(0, 2*realHeight/5, realWidth, realHeight/5);

    QRect target4(0, 3*realHeight/5, realWidth, realHeight/5);

    QRect target5(0, 4*realHeight/5, realWidth, realHeight/5);

    QRect source(0, 0, realWidth, realHeight);

    painter.drawPixmap(target1,pixmap,source);

    painter.drawPixmap(target2,pixmap,source);

    painter.drawPixmap(target3,pixmap,source);

    painter.drawPixmap(target4,pixmap,source);

    painter.drawPixmap(target5,pixmap,source);

}

void MainWindow::resizeEvent(QResizeEvent *e)

{

    realWidth = this->width();

    realHeight = this->height();

}

void MainWindow::changeEvent(QEvent *e)

{

    QMainWindow::changeEvent(e);

    switch (e->type()) {

    case QEvent::LanguageChange:

        ui->retranslateUi(this);

        break;

    default:

        break;

    }

}

(3)继续改进(10毫秒每次,用repaint()。一次repaint(),一次paintEvent(),无积累).

#include<QPainter>

#include<QDebug>

#include<QMessageBox>

#include "mainwindow.h"

#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :

    QMainWindow(parent),

    ui(new Ui::MainWindow)

{

    ui->setupUi(this);

    this->showMaximized();

    i = 0;

    realWidth = this->width();

    realHeight = this->height();

    pixmap = QPixmap(realWidth,realHeight);

    connect(this,SIGNAL(haveData(QPoint)),this,SLOT(getPointAndDraw(QPoint)));

    connect(&timer,SIGNAL(timeout()),this,SLOT(getPoint()));

    timer.start(10);

}

MainWindow::~MainWindow()

{

    delete ui;

}

void MainWindow::getPoint()

{

    if(i < realWidth)

    {

        point = QPoint(i,(uint(qrand())) % realHeight);

        i++;

    }

    else

    {

        i = i % realWidth;

        point = QPoint(i,(uint(qrand())) % realHeight);

        i++;

    }

    emit haveData(point);

}

void MainWindow::getPointAndDraw(QPoint point)

{

    index = point.x();

    QPainter painter(&pixmap);

    painter.setPen(Qt::green);

    painter.drawLine(lastPoint,point);

    painter.setPen(Qt::black);

    painter.setBrush(Qt::red);

    painter.drawRect(index+1,0,5,realHeight);

    if(point.x() < realWidth-1)

        lastPoint = point;

    else

        lastPoint = QPoint(0,0);

   this->repaint(index-1,0,5,realHeight);

}

void MainWindow::paintEvent(QPaintEvent *e)

{

    //return ;

    QPainter painter(this);

    QRect target1(0, 0, realWidth, realHeight/5);

    QRect target2(0, realHeight/5, realWidth, realHeight/5);

    QRect target3(0, 2*realHeight/5, realWidth, realHeight/5);

    QRect target4(0, 3*realHeight/5, realWidth, realHeight/5);

    QRect target5(0, 4*realHeight/5, realWidth, realHeight/5);

    QRect source(0, 0, realWidth, realHeight);

    painter.drawPixmap(target1,pixmap,source);

    painter.drawPixmap(target2,pixmap,source);

    painter.drawPixmap(target3,pixmap,source);

    painter.drawPixmap(target4,pixmap,source);

    painter.drawPixmap(target5,pixmap,source);

}

void MainWindow::resizeEvent(QResizeEvent *e)

{

    realWidth = this->width();

    realHeight = this->height();

}

void MainWindow::changeEvent(QEvent *e)

{

    QMainWindow::changeEvent(e);

    switch (e->type()) {

    case QEvent::LanguageChange:

        ui->retranslateUi(this);

        break;

    default:

        break;

    }

}

目录
相关文章
|
消息中间件 调度 Windows
|
2月前
|
算法 编译器 Linux
【Qt4 部署】ARM系统上使用Qt 4 进行开发的QWS 等环境变量部署
【Qt4 部署】ARM系统上使用Qt 4 进行开发的QWS 等环境变量部署
25 0
|
2月前
|
网络协议 C++
C++ Qt开发:QTcpSocket网络通信组件
`QTcpSocket`和`QTcpServer`是Qt中用于实现基于TCP(Transmission Control Protocol)通信的两个关键类。TCP是一种面向连接的协议,它提供可靠的、双向的、面向字节流的通信。这两个类允许Qt应用程序在网络上建立客户端和服务器之间的连接。Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用`QTcpSocket`组件实现基于TCP的网络通信功能。
44 8
C++ Qt开发:QTcpSocket网络通信组件
|
12天前
|
开发框架 编译器 C++
Qt:一个强大的跨平台C++应用程序开发框架
Qt:一个强大的跨平台C++应用程序开发框架
29 1
|
12天前
|
开发框架 Linux C++
Qt:强大的跨平台C++应用程序开发框架
Qt:强大的跨平台C++应用程序开发框架
42 3
|
15天前
|
开发框架 数据可视化 编译器
Qt的魅力:探索跨平台图形界面开发之旅
Qt的魅力:探索跨平台图形界面开发之旅
28 1
|
1月前
|
图形学 Python 容器
【PyQt5桌面应用开发】3.Qt Designer快速入门(控件详解)
【PyQt5桌面应用开发】3.Qt Designer快速入门(控件详解)
52 0
|
1月前
qt开发使用camera类获取摄像头信息并拍照保存
qt开发使用camera类获取摄像头信息并拍照保存
|
2月前
|
监控 C++
C++ Qt开发:QProcess进程管理模块
Qt是一个跨平台的C++图形库,简化了窗体应用开发,支持通过拖放组件提升效率。本章节关注`QProcess`组件,它用于控制和管理进程,例如执行命令、运行可执行文件及与外部进程通信。`QProcess`提供多种方法如`start`、`waitForStarted`和`waitForFinished`等,实现启动、监控和交互。示例展示了如何使用`QProcess`获取系统进程和信息,通过`tasklist`和`systeminfo`命令,并将结果展示在`QTreeWidget`中。
33 0
C++ Qt开发:QProcess进程管理模块
|
2月前
|
存储 C++ 网络架构
C++ Qt开发:QUdpSocket实现组播通信
Qt教程:使用`QUdpSocket`实现UDP组播通信。通过设置套接字选项、绑定端口、加入和离开组播组,以及发送和接收数据报,简化跨平台窗体应用开发。关键函数包括`setSocketOption`设置多播TTL,`bind`绑定地址和端口,`joinMulticastGroup`加入组播,`leaveMulticastGroup`退出,`writeDatagram`发送,和`readDatagram`接收数据报。
38 1
C++ Qt开发:QUdpSocket实现组播通信