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)。
如果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;
    }
}

参考:http://www.cnblogs.com/SkylineSoft/articles/2046303.html

http://www.informit.com/articles/article.aspx?p=1405227&seqNum=4

时间: 2024-10-10 18:21:11

Qt 中update()和repaint()的区别的相关文章

hibernate中update与saveOrUpdate的区别

[转]hibernate中update与saveOrUpdate的区别 分类: Hibernate总结 2009-11-17 00:04 2121人阅读 评论(0) 收藏 举报 hibernatesession数据库javadaoapplication 先来点概念: 在Hibernate中,最核心的概念就是对PO的状态管理.一个PO有三种状态: 1.未被持久化的VO 此时就是一个内存对象VO,由JVM管理生命周期 2.已被持久化的PO,并且在Session生命周期内 此时映射数据库数据,由数据库

Qt常用函数 记录(update erase repaint 的区别)

一界面重载函数使用方法:1在头文件里定义函数protected: void paintEvent(QPaintEvent *event); 2 在CPP内直接重载void ----------::paintEvent(QPaintEvent *){//重载函数体} 执行条件:界面有任何变动都会执行特别:有时候会积累变化,既界面发生变化时不是立刻执行,可能几次变化合并为只执行一次.如果要立即执行需要调用函数详细使用见http://www.cnblogs.com/hnrainll/archive/2

Unity3D中Update()与FixedUpdate()的区别

Unity3D中Update()与FixedUpdate()的区别是什么呢?从字面上理解,它们都是在更新时会被调用,并且会循环的调用.但是Update会在每次渲染新的一帧时,被调用.而FixedUpdate会在每个固定的时间间隔被调用,那么要是Update 和FixedUpdate的时间间隔一样,是不是就一样呢?答案是不一定,因为Update受当前渲染的物体,更确切的说是三角形的数量影响,有时快有时慢,帧率会变化,update被调用的时间间隔就发生变化.但是FixedUpdate则不受帧率的变化

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). 如果w是负数,它被width()-x替换,并且如果h是负数,它被height()-y替换. 如果你需要立即重新绘制,建议使用repaint(), 比如在动画期间.在绝大多数情况下,update()更好

4.关于QT中的QFile文件操作,QBuffer,Label上添加QPixmap,QByteArray和QString之间的区别,QTextStream和QDataStream的区别,QT内存映射(

 新建项目13IO 13IO.pro HEADERS += \ MyWidget.h SOURCES += \ MyWidget.cpp QT += gui widgets network CONFIG += C++11 MyWidget.h #ifndef MYWIDGET_H #define MYWIDGET_H   #include <QWidget>   class MyWidget : public QWidget {     Q_OBJECT public:     expli

(转)QT中QWidget、QDialog及QMainWindow的区别

QWidget类是所有用户界面对象的基类. 窗口部件是用户界面的一个基本单元:它从窗口系统接收鼠标.键盘和其它事件,并且在屏幕上绘制自己.每一个窗口部件都是矩形的,并且它们按Z轴顺序排列.一个窗口部件可以被它的父窗口部件或者它前面的窗口部件盖住一部分. QMainWindow 类提供一个有菜单条.锚接窗口(例如工具条)和一个状态条的主应用程序窗口.主窗口通常用在提供一个大的中央窗口部件(例如文本编辑或者绘制画布)以及周围 菜单.工具条和一个状态条.QMainWindow常常被继承,因为这使得封装

QT中QWidget、QDialog及QMainWindow的区别

QWidget类是所有用户界面对象的基类. 窗口部件是用户界面的一个基本单元:它从窗口系统接收鼠标.键盘和其它事件,并且在屏幕上绘制自己.每一个窗口部件都是矩形的,并且它们按Z轴顺序排列.一个窗口部件可以被它的父窗口部件或者它前面的窗口部件盖住一部分. QMainWindow 类提供一个有菜单条.锚接窗口(例如工具条)和一个状态条的主应用程序窗口.主窗口通常用在提供一个大的中央窗口部件(例如文本编辑或者绘制画布)以及周围 菜单.工具条和一个状态条.QMainWindow常常被继承,因为这使得封装

QT中关闭应用程序和窗口的函数(quit(),exit()以及close()的区别)

使用QT编辑界面,其中带来很大方便的一点就是Qt中自带丰富的.种类齐全的类及其功能函数,程序员可以在编辑程序的过程中简单地直接调用.关于窗口关闭的操作,在这里指出常用的三个槽,即quit(),exit()以及close().    首先说明窗口退出时,系统提示对话框的代码编辑.对主程序的退出,可以调用成员函数exit(),同时也可以调用槽quit(),二者此时都能起到关闭应用程序的作用.只是应注意二者调用的方式不同.如下程序示例:        {         QApplication* a

【转】QT中QWidget、QDialog及QMainWindow的区别

QWidget类是所有用户界面对象的基类. 窗口部件是用户界面的一个基本单元:它从窗口系统接收鼠标.键盘和其它事件,并且在屏幕上绘制自己.每一个窗口部件都是矩形的,并且它们按Z轴顺序排列.一个窗口部件可以被它的父窗口部件或者它前面的窗口部件盖住一部分. QMainWindow 类提供一个有菜单条.锚接窗口(例如工具条)和一个状态条的主应用程序窗口.主窗口通常用在提供一个大的中央窗口部件(例如文本编辑或者绘制画布)以及周围 菜单.工具条和一个状态条.QMainWindow常常被继承,因为这使得封装