PDA

View Full Version : Low speed drawing with qpainter



NavidMicro
3rd May 2018, 04:45
hi , i'm new to qt
i have low speed in this app
please help




void MainWindow::LoadGages(void)
{
QImage sb_img(":/new/prefix1/spb");
QImage tb_img(":/new/prefix1/tkb");
QImage nd_img(":/new/prefix1/nd");
QImage cn_img(":/new/prefix1/cen");
QImage ov_img(":/new/prefix1/ov");

sb = sb.fromImage(sb_img.scaled(450,450,Qt::IgnoreAspec tRatio,Qt::SmoothTransformation));
tb = tb.fromImage(tb_img.scaled(450,450,Qt::IgnoreAspec tRatio,Qt::SmoothTransformation));
nd = nd.fromImage(nd_img.scaled(146,115,Qt::IgnoreAspec tRatio,Qt::SmoothTransformation));
cn = cn.fromImage(cn_img.scaled(41,41,Qt::IgnoreAspectR atio,Qt::SmoothTransformation));
ov = ov.fromImage(ov_img.scaled(400,325,Qt::IgnoreAspec tRatio,Qt::SmoothTransformation));

speed=103;
takho=103;

qreal alpha=0.0;

for(qreal roty=270;roty<=360;roty+=5)
{
QPixmap Left=drawGauge(sb,speed,450,0,0,roty,225,225,alpha );
QPixmap Right=drawGauge(tb,speed,450,0,0,-roty,225,225,alpha);
alpha+=0.15;
ui->label->setPixmap(drawBoth(Left,Right));
QApplication::processEvents();
}

for(qreal val=103;val<=370;val+=5)
{
QPixmap Left=drawGauge(sb,val,450,0,0,0,0,0,1.0);
QPixmap Right=drawGauge(tb,val,450,0,0,0,0,0,1.0);
ui->label->setPixmap(drawBoth(Left,Right));
QApplication::processEvents();
}

for(qreal val=370;val>=103;val-=5)
{
QPixmap Left=drawGauge(sb,val,450,0,0,0,0,0,1.0);
QPixmap Right=drawGauge(tb,val,450,0,0,0,0,0,1.0);
ui->label->setPixmap(drawBoth(Left,Right));
QApplication::processEvents();
}

QPixmap Left=drawGauge(sb,103,450,0,0,0,0,0,1.0);
QPixmap Right=drawGauge(tb,103,450,0,0,0,0,0,1.0);
ui->label->setPixmap(drawBoth(Left,Right));

//timerId=startTimer(1);
update();
}

QPixmap MainWindow::drawBoth(QPixmap g1,QPixmap g2)
{
QPainter p;
QPixmap win(ui->label->size());
win.fill(Qt::transparent);
QRect winR(ui->label->x(),ui->label->y(),ui->label->width(),ui->label->height());
p.begin(&win);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
p.setRenderHint(QPainter::HighQualityAntialiasing) ;

p.drawPixmap(10,25,g1);
p.drawPixmap(winR.x()+winR.width()-450-75,25,g2);

p.end();
return win;
}

QPixmap MainWindow::drawGauge(QPixmap Gauge,qreal value,int scale,qreal z,qreal x,qreal y,qreal tx,qreal ty,qreal alpha)
{
QPainter p;
QPixmap win(Gauge.size());
win.fill(Qt::transparent);
p.begin(&win);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
p.setRenderHint(QPainter::HighQualityAntialiasing) ;
p.drawPixmap(0,0,Gauge);
p.setTransform(GetRotation(value,Qt::ZAxis,(450/2)+5,(450/2)+5));
p.setViewport(p.viewport().x()-5,p.viewport().y()-5,p.viewport().width(),p.viewport().height());
p.drawPixmap(450/2,450/2,nd);
p.resetMatrix();
p.drawPixmap((450/2)-20,(450/2)-20,cn);
p.setOpacity(0.2);
p.drawPixmap(25,25,ov);
p.end();

QPixmap gauge=win;
win.fill(Qt::transparent);
p.begin(&win);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
p.setRenderHint(QPainter::HighQualityAntialiasing) ;
p.setTransform(GetRotation(z,Qt::ZAxis,tx,ty));
p.drawPixmap(0,0,gauge);
p.end();

gauge=win;
win.fill(Qt::transparent);
p.begin(&win);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
p.setRenderHint(QPainter::HighQualityAntialiasing) ;
p.setTransform(GetRotation(x,Qt::XAxis,tx,ty));
p.drawPixmap(0,0,gauge);
p.end();

gauge=win;
win.fill(Qt::transparent);
p.begin(&win);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
p.setRenderHint(QPainter::HighQualityAntialiasing) ;
p.setTransform(GetRotation(y,Qt::YAxis,tx,ty));
p.setOpacity(alpha);
p.drawPixmap(0,0,gauge);
p.end();

gauge=win;
win.fill(Qt::transparent);
p.begin(&win);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
p.setRenderHint(QPainter::HighQualityAntialiasing) ;
p.setOpacity(alpha);
p.drawPixmap(0,0,gauge);
p.end();

QImage _retval = win.toImage();
QPixmap retval = retval.fromImage(_retval.scaled(scale,scale,Qt::Ig noreAspectRatio,Qt::SmoothTransformation));

return retval;
}

QTransform MainWindow::GetRotation(qreal rotation,Qt::Axis axis,qreal dx,qreal dy)
{
QTransform qtr;
qtr.translate(dx,dy);
qtr.rotate(rotation,axis);
qtr.translate(-dx,-dy);
return qtr;
}

high_flyer
3rd May 2018, 11:10
Well, there are many optimizations you can do.
First, you are creating all the objects on the stack locally for each method, so they get destroyed and created for each method call - and creation and deletion are very expensive operations.
Use members instead, this will have them created only once.

Then, it seems you are emulating animation by drawing on the pixmaps and then settings these pixmaps into lables, which is also very expensive.
Why don't you draw directly on to the label/widget?

When you use toImage() you are copying that image in another QImage to use as input to fromImage() - if you use the output of toImage() directly in fromImage() you will save the copying of the image which is also very expensive.

On top of that be sure to build with -O2 optimization level.

I am sure there are many other such things that can be made better - maybe some other forum members can see and point them out.

All these things will make your code faster, but in my opinion you are using the wrong solution to the problem you have - which animating graphics - and doing that in the widget world is not efficient no matter how well you trim your code.
Doing this in QML will make your UI fast, and save you code as well.
I strongly urge you to look in to QML and how to implement what you have here in QML.
Or alternatively use the QGraphicsView framework (https://doc.qt.io/qt-5.10/graphicsview.html)

NavidMicro
4th May 2018, 03:37
Thank you for your answare...

now, i want rotate drawn qpixmap




void MainWindow::paintEvent(QPaintEvent *)
{
QPainter painter(this);
//painter.setPen(Qt::black);
painter.setBrush(Qt::black);
painter.drawRect(0,0,1360,512);

painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::SmoothPixmapTransf orm);
painter.setRenderHint(QPainter::HighQualityAntiali asing);

int speedoX=25,speedoY=25;

painter.resetMatrix();
painter.resetTransform();
painter.setOpacity(1.0);

painter.drawPixmap(speedoX,speedoX,sb);
painter.setTransform(GetRotation(speedo.value,Qt:: ZAxis,speedoX+((450/2)+5),speedoY+((450/2)+5)));
painter.setViewport(painter.viewport().x()-5,painter.viewport().y()-5,painter.viewport().width(),painter.viewport().he ight());
painter.drawPixmap(speedoX+(450/2),speedoY+(450/2),nd);
painter.resetMatrix();
painter.drawPixmap(speedoX+((450/2)-20),speedoY+((450/2)-20),cn);
painter.setOpacity(0.3);
painter.drawPixmap(speedoX+25,speedoY+25,ov);


int takhoX=1360-450-75,takhoY=25;

painter.resetMatrix();
painter.resetTransform();
painter.setOpacity(1.0);

painter.drawPixmap(takhoX,takhoY,tb);
painter.setTransform(GetRotation(takho.value,Qt::Z Axis,takhoX+((450/2)+5),takhoY+((450/2)+5)));
painter.setViewport(painter.viewport().x()-5,painter.viewport().y()-5,painter.viewport().width(),painter.viewport().he ight());
painter.drawPixmap(takhoX+(450/2),takhoY+(450/2),nd);
painter.resetMatrix();
painter.drawPixmap(takhoX+((450/2)-20),takhoY+((450/2)-20),cn);
painter.setOpacity(0.3);
painter.drawPixmap(takhoX+25,takhoY+25,ov);

}

how can i do ?