Спите внутри цикла, который использует painttevent в qt Stack Overflow

По сути, я хочу нарисовать прямоугольники для каждого числа в моем списке. Чем больше число, тем больше прямоугольник.
Моя проблема в том, когда я действительно хочу сделать это, шаг за шагом, и ждать несколько секунд между каждым рисунком. Я искал несколько решений, но я не могу заставить их работать для этого конкретного случая. Я видел, что могу использовать fflush для освобождения всего, что находится в буфере, но я не знаю, как я могу использовать это для этого.

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;
}

Любая помощь могла бы быть полезна.

1

Решение

sleep () не будет работать для этого — он блокирует цикл событий Qt и не дает Qt выполнять свою работу, пока он спит.

Вам нужно сохранить одну или несколько переменных-членов, чтобы запомнить текущее состояние изображения, которое вы хотите нарисовать, и реализовать paintEvent (), чтобы нарисовать только текущее одиночное изображение. paintEvent () (как и любая функция, выполняющаяся в потоке GUI Qt) всегда должен возвращаться немедленно, и никогда не спать или блокироваться.

Затем, чтобы реализовать анимационную часть, настройте объект QTimer, чтобы он вызывал для вас слот через равные промежутки времени (например, один раз каждые 1000 мс или как вам часто угодно). Реализуйте этот слот, чтобы настроить ваши переменные-члены на их следующее состояние в последовательности анимации (например, rectangle_size ++ или что-то еще), а затем вызовите update () для вашего виджета. update () скажет Qt снова вызвать paintEvent () для вашего виджета как можно скорее, поэтому ваше отображение будет обновлено до следующего кадра очень скоро после того, как ваш метод слота вернется.

Ниже приведен тривиальный пример техники; при запуске он показывает красный прямоугольник, становящийся все больше и меньше:

// 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();
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]