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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM