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

拥有回忆 提交于 2019-12-11 03:38:51

问题


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.


回答1:


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



回答2:


As you've guessed, QTimer is the correct mechanism to use here. How to go about setting it up?

Here's one option:

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

}



回答3:


Try something like this:

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

};

Don't forget to run moc on this file, although if your class is a QObject you probably already do it.




回答4:


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

}

Use sleep() The function called sleep(int ms) declared in which makes the program wait for the time in milliseconds specified.



来源:https://stackoverflow.com/questions/23091664/qt-how-to-loop-a-method-every-second-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!