Frage

Basically what I wanna do is to draw rectangles for each number in my list. The bigger the number is, the larger the rectangle is. My problem is when I actually wanna do it, step-by-step, and waiting a few seconds between every drawing. I've looked out for a few solutions but I can't get them to work for this particular case. I saw I could use fflush to release whatever it's in the buffer but I don't know how I can use it for this.

QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setBrush(QBrush(Qt::green, Qt::SolidPattern));
int weight=300/lista.size;
int posx=weight;
for (int i=1; i<=lista.size; i++){
        List_node * node = list.get_element_at(i);
            int num=node->getValue(); //this returns the value of the node
        if (i==3){
                painter.setBrush(QBrush(Qt::red, Qt::SolidPattern)); // this line is to draw a rectangle with a different color. Testing purposes.
         }
        painter.drawRect(posx,400-(num*10),weight,num*10);
        sleep(1); //this sleep isn't working correctly.
        painter.setBrush(QBrush(Qt::green, Qt::SolidPattern));
        posx+=weight;
 }

Any help would be really appreciated.

War es hilfreich?

Lösung

sleep() won't work for this -- it blocks the Qt event loop and keeps Qt from doing its job while it is sleeping.

What you need to do is keep one or more member variables to remember the current state of the image you want to draw, and implement paintEvent() to draw that current single image only. paintEvent() (like every function running in Qt's GUI thread) should always return immediately, and never sleep or block.

Then, to implement the animation part of things, set up a QTimer object to call a slot for you at regular intervals (e.g. once every 1000mS, or however often you like). Implement that slot to adjust your member variables to their next state in the animation-sequence (e.g. rectangle_size++ or whatever) and then call update() on your widget. update() will tell Qt to call paintEvent() again on your widget as soon as possible, so your display will be updated to the next frame very shortly after your slot method returns.

Below is a trivial example of the technique; when run it shows a red rectangle getting larger and smaller:

// begin demo.h
#include <QWidget>
#include <QTimer>

class DemoObj : public QWidget
{
Q_OBJECT

public:
   DemoObj();

   virtual void paintEvent(QPaintEvent * e);

public slots:
   void AdvanceState();

private:
   QTimer _timer;
   int _rectSize;
   int _growthDirection;
};

// begin demo.cpp
#include <QApplication>
#include <QPainter>
#include "demo.h"

DemoObj :: DemoObj() : _rectSize(10), _growthDirection(1)
{
   connect(&_timer, SIGNAL(timeout()), this, SLOT(AdvanceState()));
   _timer.start(100);   // 100 milliseconds delay per frame.  You might want to put 2000 here instead
}

void DemoObj :: paintEvent(QPaintEvent * e)
{
   QPainter p(this);
   p.fillRect(rect(), Qt::white);
   QRect r((width()/2)-_rectSize, (height()/2)-_rectSize, (_rectSize*2), (_rectSize*2));
   p.fillRect(r, Qt::red);
}

void DemoObj :: AdvanceState()
{
   _rectSize += _growthDirection;
   if (_rectSize > 50) _growthDirection = -1;
   if (_rectSize < 10) _growthDirection = 1;
   update();
}

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

   DemoObj obj;
   obj.resize(150, 150);
   obj.show();
   return app.exec();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top