PDA

View Full Version : QWidget update get so cpu usage



danics
18th August 2012, 11:07
hi everyone,

i have a timer with 10 ms interval connected to a method that run update function of my widget and i havent paintEvent either, but i get 25 percent cpu usage for my application and 25 percent for xorg, why updating a fixed widget get such a horrible cpu, if i comment update function my cpu usage is 1percent,
do we have any other function for updating widgets?

tnx.

mvuori
18th August 2012, 11:44
The problem is probably not in the update function, but the things that it has to do 100 times a second! Your widget is very busy updating itself. Without knowing anything about your application it is hard to understand why something should be updated 100 times a second for UI purposes.

danics
18th August 2012, 12:11
i want to create a smooth animation from a start point to end point in constant time like 4 seconds from 0 to 360, so after using Animation framework and some Gl painting i figured out that if myself paint this animation with timer and changing paintevent my cpu usage is less than other ways, but its not enough too, so i think maybe my painting functions get this much cpu and i comment all painting functions, but i realized my cpu usage havent any change (maybe only two percent), after all comments i have a white widget that update only itself in this time and nothing changed too, but it get this much cpu, as i saied if i comment update my application cpu usage get only 1 percent.
after all, if you have any ideas about how i must painting a smotth animation in constant time without increase of my steps i would thank of you.

d_stranz
19th August 2012, 00:22
The human eye cannot detect anything that changes faster than about 30 times per second, and even then can't process the changes in the brain unless the changes are gradual (like a movie). So it makes no sense at all to try to animate anything faster than 10 - 20 steps per second (i.e a timer with timeout of 100 - 50 ms). Otherwise you're just burning up CPU cycles for no good reason and slowing everything else down.

If your animation steps can be pre-computed (that is, drawn into a series of images once instead of being drawn each step in real time), then store the images as resources in your application and simply display each image one after the other using QImage or QPixmap. This will probably be much faster than a bunch of QPainter operations with pens, brushes, and shapes.

danics
19th August 2012, 20:45
i dont realy get it, i change everything my steps and my constant time too, but nothing change
ok i think i cant solve my current situation with GraphicsView or widgets painting, any way this is a sample code like what i have



MyHand::MyHand(QGraphicsItem *parent) :
QGraphicsLineItem(parent)
{
handchanger = new QPropertyAnimation(this, "rotationAngle");
connect(handchanger, SIGNAL(finished()), this, SLOT(reanimate()));
handchanger->setDuration(20000);
handchanger->setStartValue(0);
handchanger->setEndValue(360);
handchanger->setEasingCurve(QEasingCurve::Linear);
setCacheMode(ItemCoordinateCache);
}

void MyHand::setRotationValue(qreal angle)
{
if(m_angle != angle)
{
m_angle = angle;
QPointF o = boundingRect().bottomLeft();
QTransform t;
t.translate(o.x(), o.y());
t.rotate(m_angle, Qt::ZAxis);
t.translate(-o.x(), -o.y());
setTransform(t);
}
}
void MyHand::reanimate()
{
handchanger->start();
}

void handscene::drawBackground(QPainter *painter, const QRectF &rect)
{
if(hand->line() == QLineF(0,0,0,0))
{
hand->setPen(QPen(Qt::black, 2));
hand->setLine(rect.width() / 2, rect.height() / 2, rect.width()/2, 0);
addItem(hand);
hand->start();
hand->setZValue(10);


back = new QGraphicsEllipseItem(0,0,rect.width(), rect.height());
back->setBrush(Qt::yellow);
back->setZValue(5);
addItem(back);
}
}

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QGraphicsView v;
v.setScene(new radarcircle);
// v.setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
v.setGeometry(0, 0, 700, 700);
v.setSceneRect(0,0 ,700,700);
v.show();

return a.exec();
}


in any rate and duration time i have 50% cpu usage total for xorg and my application,
i m using QGLWIdget for my GraphicsView viewport and now my gpu usage is 90% and this is so bad too,
anyone have any idea how can i reduce this much usages?
i thought of XOR painting like old times in Ms Dos :(.
this is a simple rotate animation and realy i think it should use only 5% of cpu in worst case.

ChrisW67
20th August 2012, 00:26
How does this behave? It barely registers on my machine


#include <QtGui>

class RadarScene: public QGraphicsScene
{
Q_OBJECT

enum { Radius = 100, SweepTime = 20000 };

public:
RadarScene(QObject *p = 0): QGraphicsScene(p), m_hand(0), m_tick(0)
{
QGraphicsEllipseItem *e = new QGraphicsEllipseItem(-Radius, -Radius, 2 * Radius, 2 * Radius);
e->setBrush(Qt::yellow);
addItem(e);

m_hand = new QGraphicsLineItem(0, 0, Radius, 0);
m_hand->setPen(QPen(Qt::black, 2));
addItem(m_hand);

m_timer = new QTimer(this);
connect(m_timer, SIGNAL(timeout()), SLOT(tick()));
m_timer->start(SweepTime / 360);
}

private slots:
void tick()
{
m_tick = (m_tick + 1) % 360;
m_hand->setRotation(m_tick);
}

private:
QGraphicsLineItem *m_hand;
int m_tick;
QTimer *m_timer;
};


int main(int argc, char **argv)
{
QApplication app(argc, argv);

RadarScene r;
QGraphicsView w(&r);
w.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
w.show();

return app.exec();
}
#include "main.moc"


If you are using an OpenGL renderer and there is no OpenGL accelerated video driver then you system may be falling back to a software OpenGL implementation. This will be CPU intensive.

danics
20th August 2012, 05:43
first thanks for yout answer and your code

If you are using an OpenGL renderer and there is no OpenGL accelerated video driver then you system may be falling back to a software OpenGL implementation. This will be CPU intensive.

yes i know that and i saied before when i m using gl rendering my GPU usage go to 90% and its bad too (we wouldnt implement a 3d game :D)

and about your code, i test it and please change radius to 350 and your timer sweep to 5000 in my system cpu usage of xorg and our application totally is 60%

and i dont think we impement it in more than 30 frames per second ???

thanks again.

ChrisW67
20th August 2012, 07:42
5000 milliseconds to do 360 steps is over 70 updates per second. Even so, I don't a see a ridiculous CPU load; about 10% of one core between my application and X with default renderer. Increasing the steps to 3 degrees and doing 120 per revolution (24fps movie rate) drops that to < 5.

danics
20th August 2012, 08:07
5000 milliseconds to do 360 steps is over 70 updates per second. Even so, I don't a see a ridiculous CPU load; about 10% of one core between my application and X with default renderer. Increasing the steps to 3 degrees and doing 120 per revolution (24fps movie rate) drops that to < 5.

ok i get your point, you want me to fixed timer interval to 50 ms and change my steps for increasing my speed, i did this before but what about smooth animating? it seems like a jump not continusely rounding,
any way my cpu load is 20% in this manner, are you sure you change your radius?