void Qwidget::repaint (int x, int y, int w, int h, bool erase = TRUE) [slot]
by calling PaintEvent () immediately to redraw the widget directly, if erase is true, QT erases the area (x,y,w,h) before the PaintEvent () call.
If W is a negative number, it is replaced by the width ()-X, and if H is a negative number, it is replaced by the height ()-Y. If you need to redraw now, it is recommended to use repaint (),
For example, during an animation. In most cases, update () is better because it allows QT to optimize speed and prevent flicker.
Warning: If you call repaint () in a function and it is called by PaintEvent () yourself, you may see a wireless loop.
The update () function never generates a loop.
void Qwidget::update () [Groove]
Updates the widgets and when QT returns to the main event, it plans the drawing events to be processed. This allows QT to be optimized for faster speeds than calling repaint () and
Less flicker. The result of several calls to update () is usually just one paintevent () call. Qt usually erases this widget before PaintEvent () is called.
Area, only if the Wrepaintnoerase widget tag is set.
The key point in this distinction is that repaint () is called immediately paintevent (), and update () is executed several times to invoke PaintEvent ().
This results in an update () that causes the task in PaintEvent () to be replaced by update (). PaintEvent () is getting more and more tasks in the backlog.
Examples of programs:
(1) The situation when the problem occurs (10 milliseconds each time, with update (). PaintEvent () has accumulated a lot of processing tasks):
#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) Refresh every 1000 milliseconds, use update(). One second has enough time to process paintEvent(), no accumulation.
#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) Continue to improve (10 milliseconds each time, use repaint(). One repaint(), one paintEvent(), no accumulation).
#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;
}
}