Search code examples
c++qtloopsqtimer

QT: How to loop a method every second? C++


I've created a Qt project which displays a circle on a widget. Then I have a method which redraws the circle at different positions every time I call the method. What I want is to run that method in a for loop, say ten times, and be shown each of the 10 positions that the circle is redrawn in every one second.

Something along the lines of:

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

}

I've read about QTimer, but do not know how to use it. And the sleep function does not work.


Solution

  • All you need to do is to trigger an update() from the timer event. The update() method schedules a paintEvent on the widget.

    It is invalid to paint on a widget outside of the paintEvent - that's the mistake that all other answers did at the time I posted this answer. Merely calling the paintEvent method is not a workaround. You should call update(). Calling repaint() would also work, but do so only when you have understood the difference from update() and have a very good reason for doing so.

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