QThread loop and QTimer



  • Hello to everyone,
    I'm new in this forum: so please excuse me if my question is obvious.

    I'm trying to implement a GUI application. This app must call "Core" class, which is derived by QThread.
    In the Core class there is an infinite loop. There is also a timer: its timeout signal is calling a Core's slot.
    This is a sample of my code:

    @
    class Core : public QThread
    {
    Q_OBJECT

    private:
    QTimer * timer;
    volatile bool flag;

    public:
    Core(QObject *parent = 0);
    ~Core();

    protected:
    void run(void);

    public slots:
    void TimerTick(void);
    }

    // Implementation
    Core::Core( QObject *parent)
    : QThread(parent)
    {
    this->flag = false;
    this->timer = new QTimer();
    this->timer->setInterval(10);
    this->timer->moveToThread(this);
    QObject::connect(this->timer, SIGNAL(timeout()), this, SLOT(TimerTick()));
    QObject::connect(this, SIGNAL(started()), this->timer1ms, SLOT(start()));
    }

    void Core::TimerTick(void)
    {
    flag = true;
    }

    void Core::run(void)
    {
    while(!flag)
    {
    // main thread loop code
    }
    }
    @

    My program doesn't call the slot method TimerTick()
    Can anybody help me?

    Thanks in advance


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Your thread doesn't run an event loop so your timer won't run thus the slot will not get called.

    You should rather have that timer outside of your class if you really want to use your thread with a never ending loop.

    Since you're at the design stage, are you sure that the infinite loop is the way to go ?

    Hope it helps



  • BTW deriving from QThread is highly discouraged!! The QThread is designed as a wrapper around a QObject derived class.
    Read this forum:
    "How to do threads in Qt":http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
    That object will then run in a different event loop, so start your timer there and send signals or overwrite the timerEvent and do stuff in there. Maybe QBasicTimer is easier to use with the timerEvent.


  • Lifetime Qt Champion

    Jeroentje@home
    Wrapper vs derivation has been brought up several times in the last few months (here and on the mailing list)

    After some (sometimes heated) conversations, the final point made was: it depends on the use case. (That's why I also asked the OP for here reason to do an infinite loop) Most of the time using a wrapper is the way to go, but that's not always the case.



  • Thank you so much for your quick replies.
    I'd like to use an infinite loop because i want to simulate on a desktop pc an embedded firmware, which is composed by an infinite main loop and a timer with its interrupt.



  • Now I'm using the QThread as a wrapper and not as a Base Class.

    @
    /*** main function /
    QThread * thread = new QThread();
    Core * pCore = new Core();
    pCore->moveToThread(thread);
    QObject::connect(thread, SIGNAL(started()), pCore, SLOT(CoreStart()));
    thread->start();
    /
    ****************/

    class Core : public QObject
    {
      Q_OBJECT
     
    private:
      QTimer * timer;
      volatile bool flag;
     
    public:
      Core(QObject *parent = 0);
      ~Core();
     
    private:
       void run(void);
    
    public slots:
        void CoreStart();
    
    private slots:
      void TimerTick(void);
    }
     
    // Implementation
    Core::Core( QObject *parent)
      :  QObject(parent)
    {
      this->flag = false;
    }
    
    void Core::CoreStart(void)
    {
        // the thread affinity of timer is my thread
        this->timer = new QTimer();
        this->timer->setInterval(10);
         QObject::connect(this->timer, SIGNAL(timeout()), this, SLOT(Timer_Tick()));
    
        while(!flag)
        {
            // loop code
        }
    }
     
    void Core::TimerTick(void)
    {
      flag = true;
    }
    

    @

    Now I think that I need to implement an event loop for my thread. Is it possible?
    Otherwise, i must put my timer outside the Core class: in this case how can i emit some signal to the Core class infinite loop?

    Thanks


  • Moderators

    Essentially, an event loop IS an infinite loop. It cannot coexist with another infinite loop on the same thread.

    [quote author="aenima1891" date="1373641819"]I'd like to use an infinite loop because i want to simulate on a desktop pc an embedded firmware, which is composed by an infinite main loop and a timer with its interrupt.
    [/quote]Qt is an event-driven framework -- the event loop can easily produce periodic "interrupts". Something like this:

    @
    // Class header
    class Core : public QObject {
    Q_OBJECT

    public:
    Core(QObject* parent = 0);

    public slots:
    void interrupt();
    };
    @

    @
    // Program
    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    Core core;
    QTimer timer;

    // Invoke interrupt() whenever the timer fires
    QObject::connect(&timer, SIGNAL(timeout()),
            &core, SLOT(interrupt()));
    
    // Fire the timer every 1 second
    timer.start(1000);
    
    // Start the event loop
    return a.exec()
    

    }
    @

    And if Core::interrupt() is a short function, you can run your simulation in the main thread alongside the GUI, networking, etc.



  • Thanks JKSH.
    Can I add a QEventLoop to my thread and insert a call QEventLoop::exec() inside my "thread loop"? This should force the code to reenter the event loop and so manage the signal emitted by the timer.

    @
    while(!flag)
    {
    // thread looop
    loop.exec();
    }
    @

    Is it possible?


  • Moderators

    [quote author="aenima1891" date="1373647595"]Thanks JKSH.[/quote]You're welcome :)
    [quote]Can I add a QEventLoop to my thread and insert a call QEventLoop::exec() inside my "thread loop"?[/quote]No. QEventLoop::exec() is a blocking function.

    Like I said before, an event loop is an infinite loop. If you nest an infinite loop inside another infinite loop, the outer one will only run once. And if you break out of your event loop, your timer signals will get lost.

    Try writing your simulation without the infinite while loop.


  • Lifetime Qt Champion

    Could you show us a bit of your infinite loop code ? That would allow us to give you better hints on how to implement your simulation


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.