Я создал проект Qt, который отображает круг на виджете.
Затем у меня есть метод, который перерисовывает круг в разных позициях каждый раз, когда я вызываю метод.
Я хочу запустить этот метод в цикле for, скажем десять раз, и показать каждую из 10 позиций, в которых круг перерисовывается каждую секунду.
Что-то вроде:
void method::paintEvent(QPaintEvent * p)
{
//code
for(int i=0; i<10;i++)//do this every second
{
method(circle[i]); //co-ordinates change
circle[i].pain( & painter); //using QPainter
}
//code
}
Я читал о QTimer, но не знаю, как его использовать. И функция сна не работает.
Все, что вам нужно сделать, это вызвать update()
из события таймера. update()
метод планирует paintEvent
на виджете.
Недопустимо рисовать на виджете за пределами paintEvent
— это ошибка, которую сделали все остальные ответы в то время, когда я опубликовал этот ответ. Просто зовет paintEvent
метод не обходной путь. Вам следует позвонить update()
, призвание repaint()
будет также работать, но делать это только тогда, когда вы поняли разницу от update()
и есть очень веская причина для этого.
class Circle;
class MyWidget : public QWidget {
Q_OBJECT
QBasicTimer m_timer;
QList<Circle> m_circles;
void method(Circle &);
void paintEvent(QPaintEvent * p) {
QPainter painter(this);
// WARNING: this method can be called at any time
// If you're basing animations on passage of time,
// use a QElapsedTimer to find out how much time has
// passed since the last repaint, and advance the animation
// based on that.
...
for(int i=0; i<10;i++)
{
method(m_circles[i]); //co-ordinates change
m_circles[i].paint(&painter);
}
...
}
void timerEvent(QTimerEvent * ev) {
if (ev->timerId() != m_timer.timerId()) {
QWidget::timerEvent(ev);
return;
}
update();
}
public:
MyWidget(QWidget*parent = 0) : QWidget(parent) {
...
m_timer.start(1000, this);
}
};
Как вы уже догадались, QTimer это правильный механизм, чтобы использовать здесь. Как это сделать?
Вот один из вариантов:
class MyClass : public QObject
{
public:
MyClass():i(0)
{
QTimer::singleShot(1000,this,SLOT(callback()));//or call callback() directly here
} //constructor
protected:
unsigned int i;
void paintEvent(QPaintEvent * p)
{
//do your painting here
}
public slots:
void callback()
{
method(circle[i]); //co-ordinates change
//circle[i].pain( & painter); //don't use QPainter here - call update instead
update();
++i;//increment counter
if(i<10) QTimer::singleShot(1000,this,SLOT(callback()));
}
}
Попробуйте что-то вроде этого:
class MyDrawer : public QObject
{
Q_OBJECT
int counter;
QTimer* timer;
public:
MyDrawer() : QObject(), counter(10)
{
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(redraw()));
timer->start(1000);
}
public slots:
void redraw()
{
method(circle[i]); //co-ordinates change
circle[i].pain( & painter);
--counter;
if (counter == 0) timer->stop();
}
};
Не забудь бежать moc
в этом файле, хотя, если ваш класс QObject, вы, вероятно, уже делаете это.
Try this.
for(int i=0; i<10;i++)//do this every second
{
method(circle[i]); //co-ordinates change
circle[i].pain( & painter);
sleep(1000);// you can also use delay(1000);
}
Используйте sleep () Объявленная функция с именем sleep (int ms), в которой программа ожидает в течение указанного времени в миллисекундах.