Start QTimer from another thread in event() function? Or other delay ?



  • Hey

    I would like to start a one-shot timmer in a

    object::event(QEvent*event)

    My object is made as follow

    object::object(){
    thread = new QThread();
    moveToThread(thread)
    thread->start();
    ... code that creates timer and configures connection on timeout.
    

    function. I'm doing some processing and I'd like to do something specific xx ms after receiving the last event of type xx. If I understand correctly if I set the delay to 100ms on timer.start(), then if I fire timer again in under 100ms the clocks reset and its another 100ms from the last call?

    But when I try to start timmer in that event function I get > WARNING: QObject::startTimer: Timers cannot be started from another thread... I read that I need to creat timmer in that thread, but I though I did that...

    TIA


  • Lifetime Qt Champion

    Leak was not correct, sorry for that. I misread the code and did not saw it was a member of your class. But you still need to destroy it manually in the destructor.

    Anyway, it's not its place.

    If you want to properly have your timer moved with the rest of your class, make said class the parent of your object. The child objects will be moved along with their parent.


  • Lifetime Qt Champion

    Hi,

    Can you show the complete code you are using ?

    By the way, you are leaking a QThread object the way you do it.

    You should rather have a controller class that manages your worker object and QThread.



  • @SGaist said in Start QTimer from another thread in event() function? Or other delay ?:

    Hi,

    Can you show the complete code you are using ?

    By the way, you are leaking a QThread object the way you do it.

    You should rather have a controller class that manages your worker object and QThread.

    I am leaking it ?o.O oh snap! I didnt get that far yet, thanks! Will give it another look...

    In general class looks like this

    
    myObject::myObject(){
        thread = new QThread();
        moveToThread(thread)
        thread->start();
        myTimer = new QTimer();
        mTimer->setSingleShot(true);
        connect(mTimer, &QTimer::timeout, this, &myObject::processData, Qt::QueuedConnection);
        // or connect(mTimer, &QTimer::timeout, this, &myObject::processData ); havent decided yet.
    }
    
    myObject::event(QEvent*event){
         if(event->type()==40000){
             mTimer->start(100)
         }
    }
    
    myObject::processData(){
        qDebug()<<"Do some stuff 100ms after last even received"
    }
    

    I wonder now... maybe I should do something QMetaObject::invokeMethod([=](){send signal to this myObject with slot creating QThread so that QThread is being made then?});??

    Tia


  • Lifetime Qt Champion

    Leak was not correct, sorry for that. I misread the code and did not saw it was a member of your class. But you still need to destroy it manually in the destructor.

    Anyway, it's not its place.

    If you want to properly have your timer moved with the rest of your class, make said class the parent of your object. The child objects will be moved along with their parent.



  • @SGaist said in Start QTimer from another thread in event() function? Or other delay ?:

    The child objects will be moved along with their parent.

    This is amazing! :D Thanks it works :D

    1fc8a68c-a0dc-46a9-8ba2-5f116f4c2f23-image.png


  • Lifetime Qt Champion

    You're welcome !

    Since you have it working now, please mark the thread as solved using the "Topic Tools" button so other forum users may know a solution has been found :-)

    Seems the cache hid the fact that you did everything already !