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