Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QObject::startTimer: Timers cannot be started from another thread
Forum Updated to NodeBB v4.3 + New Features

QObject::startTimer: Timers cannot be started from another thread

Scheduled Pinned Locked Moved Solved General and Desktop
2 Posts 2 Posters 1.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Dummie1138D Offline
    Dummie1138D Offline
    Dummie1138
    wrote on last edited by
    #1

    Hi. I have the following code/minimum reproducable example.

    What the code does: There is an object that manages all device connections. In the controller, I am placing this object into a separate thread because I have issues with the Qt SerialPort data reception being blocked when the titlebar is moved.

    controller.h

    #ifndef CONTROLLER_H
    #define CONTROLLER_H
    #include <QString>
    #include <QObject>
    #include <QTimer>
    #include <QTime>
    #include <QQueue>
    #include <QByteArray>
    #include <QThread>
    #include <cmath>
    
    class DeviceConnection;
    
    class Controller:public QObject
    {
        Q_OBJECT
    public:
        //singleton
        static Controller* get();
        Controller(QObject *parent = nullptr);
        QThread* devConThread = new QThread(this);  //Thread for DeviceConnection
        //There's more to this file but those objects have been omitted.
    };
    
    #endif // CONTROLLER_H
    
    

    controller.cpp

    Controller::Controller(QObject *parent) :
        QObject(parent){
        //NOTE Placing device connection on a new thread because of this:
        //FIXIT putting this onto a new thread causes issues with reconnecting.
        deviceConnection = new DeviceConnection;
        deviceConnection->moveToThread(devConThread);
        devConThread->start();
    }
    
    void Controller::reconnect(){
        deviceConnection->restartConnection();
    }
    

    deviceconnection.cpp

    DeviceConnection::DeviceConnection(){
        connectingTimer = new QTimer(this);
        connectingTimer->start(3000);
        
        serialPort_Controller = new QSerialPort(this);
        connect(connectingTimer, SIGNAL(timeout()), this, SLOT(connectDevice()));
    }
    
    //ends the connection to the device and restarts the connection procedure with the next port
    void DeviceConnection::restartConnection()
    {
        serialPort_Controller->close();
        qDebug() << "restartConnection";
        connectingTimer->start(3000);
        qDebug() << "startedTimer";
        emit lostConnection();
    }
    

    When restartConnection is triggered, I get the following output:

    restartConnection
    QObject::startTimer: Timers cannot be started from another thread
    startedTimer
    

    My confusion comes from this: how am I starting this timer from another thread? My understanding of threads is that deviceConnection is currently stored in another thread, "devConThread". And since the timer connectingTimer is being started within the deviceConnection object, the timer should be started from the same thread as the deviceConnection. I am unsure what I am doing incorrectly here.

    Please let me know if more information is required.

    sierdzioS 1 Reply Last reply
    0
    • Dummie1138D Dummie1138

      Hi. I have the following code/minimum reproducable example.

      What the code does: There is an object that manages all device connections. In the controller, I am placing this object into a separate thread because I have issues with the Qt SerialPort data reception being blocked when the titlebar is moved.

      controller.h

      #ifndef CONTROLLER_H
      #define CONTROLLER_H
      #include <QString>
      #include <QObject>
      #include <QTimer>
      #include <QTime>
      #include <QQueue>
      #include <QByteArray>
      #include <QThread>
      #include <cmath>
      
      class DeviceConnection;
      
      class Controller:public QObject
      {
          Q_OBJECT
      public:
          //singleton
          static Controller* get();
          Controller(QObject *parent = nullptr);
          QThread* devConThread = new QThread(this);  //Thread for DeviceConnection
          //There's more to this file but those objects have been omitted.
      };
      
      #endif // CONTROLLER_H
      
      

      controller.cpp

      Controller::Controller(QObject *parent) :
          QObject(parent){
          //NOTE Placing device connection on a new thread because of this:
          //FIXIT putting this onto a new thread causes issues with reconnecting.
          deviceConnection = new DeviceConnection;
          deviceConnection->moveToThread(devConThread);
          devConThread->start();
      }
      
      void Controller::reconnect(){
          deviceConnection->restartConnection();
      }
      

      deviceconnection.cpp

      DeviceConnection::DeviceConnection(){
          connectingTimer = new QTimer(this);
          connectingTimer->start(3000);
          
          serialPort_Controller = new QSerialPort(this);
          connect(connectingTimer, SIGNAL(timeout()), this, SLOT(connectDevice()));
      }
      
      //ends the connection to the device and restarts the connection procedure with the next port
      void DeviceConnection::restartConnection()
      {
          serialPort_Controller->close();
          qDebug() << "restartConnection";
          connectingTimer->start(3000);
          qDebug() << "startedTimer";
          emit lostConnection();
      }
      

      When restartConnection is triggered, I get the following output:

      restartConnection
      QObject::startTimer: Timers cannot be started from another thread
      startedTimer
      

      My confusion comes from this: how am I starting this timer from another thread? My understanding of threads is that deviceConnection is currently stored in another thread, "devConThread". And since the timer connectingTimer is being started within the deviceConnection object, the timer should be started from the same thread as the deviceConnection. I am unsure what I am doing incorrectly here.

      Please let me know if more information is required.

      sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      @Dummie1138 said in QObject::startTimer: Timers cannot be started from another thread:

      void Controller::reconnect(){
      deviceConnection->restartConnection();
      }

      Here you are calling the deviceConnection which runs in devConThread from your main thread.

      To get rid of this problem, use signals and slots - send a signal asking to reconnect, and receive it in DeviceConnection and run your timer there in the slot. This way Qt will make sure it's all done properly.

      (Z(:^

      1 Reply Last reply
      2
      • Dummie1138D Dummie1138 has marked this topic as solved on

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved