zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    python的paramiko模块简单应用
    python单线程下实现多个socket并发
    python之协程
    python之生产者消费者模型
    python进程之间修改数据[Manager]与进程池[Pool]
    python的进程间的数据交互
    vmware搭建vSAN提示磁盘不合格或者看不到磁盘的解决办法
    python之多并发socket
    OOP的几个不常用的方法
    HTTP 头和 PHP header() 函数
  • 原文地址:https://www.cnblogs.com/findumars/p/4733606.html
Copyright © 2011-2022 走看看