Multithreading application signal/slot problem



  • My application is based on two big engine:
    -the first that run the main application window (with Ui, and settings...);
    -the second that is moved to a different thread, that is used to process the serial comunication protocol (using QSerialPort).

    from the main thread emitting a signal, I open the port.
    On the second thread, once the port is opened, I'm listen to incoming byte, connecting the signal "readyRead()", to the slot "readData()" that shows me on debug console the incoming data.
    @
    private:
    QSerialPort port;
    ...
    connect(&port,SIGNAL(readyRead()),this,SLOT(readData())); (<--- inserted after serial port instantiation)
    ....
    void GCode::readData()
    {
    QByteArray data = port.readAll();
    qDebug()<<data;
    }
    @

    the problem is when the signal "readyRead()" is emitted: this error occurs
    @
    QObject: Cannot create children for a parent that is in a different thread.
    (Parent is QSerialPort(0x22fd58), parent's thread is QThread(0x1238e258), current thread is QThread(0x22fd44)
    QObject: Cannot create children for a parent that is in a different thread.
    (Parent is QSerialPort(0x22fd58), parent's thread is QThread(0x1238e258), current thread is QThread(0x22fd44)
    @
    what is the problem?
    the second thread is based on the class SerialEngine that i moved to thread with this code:
    @
    SerialEngine se;
    QThread seThread;

    se.moveToThread(&threadSe);
    seThread.start();
    @


  • Moderators

    Hi,

    When you moved your SerialEngine to your other thread, did you make sure that all its member variables got moved too? Those member variables will only get moved automatically if they are the children of the SerialEngine.



  • What do you mean with " variables will only get moved automatically if they are the children of"? All the variable in SerialEngine are defined into it.
    What could be the problem?
    [quote author="JKSH" date="1379380697"]Hi,

    When you moved your SerialEngine to your other thread, did you make sure that all its member variables got moved too? Those member variables will only get moved automatically if they are the children of the SerialEngine.[/quote]


  • Lifetime Qt Champion

    Hi,

    You port variable is created at the same time as your SerialEngine so in the the thread that instantiated it. When moving se to seThread, port is not moved with it.

    You should rather make it a pointer, and give it your SerialEngine as parent so it will be moved with it.


  • Moderators

    Member variables are not the same as children.

    All QObjects can have parent-children relationships. To create a relationship, either call QObject::setParent(), or pass the pointer of the parent object to the child's constructor.

    Example:
    @
    class BigObject : public QObject
    {
    Q_OBJECT

    private:
    double d;
    QTimer *t1;
    QTimer *t2;
    QTimer *t3;

    public:
    BigObject(QObject *parent = 0) : QObject(parent)
    {
    d = 0.0;
    t1 = new QTimer();
    t2 = new QTimer(this);
    t3 = new QTimer(t1);
    }
    };
    @
    In the code above, a BigObject has 4 member variables, but only 1 child.

    • d can never have a parent because it is not a QObject.
    • t1 has no parent because no parent was specified.
    • t2 is a child of the BigObject, because the BigObject pointer (this) was passed into its constructor.
    • t3 is a child of t1, because the t1 pointer was passed into its constructor. t3 is not a child of the BigObject.

    If I call moveToThread() on my BigObject, only t2 will be moved with it. t1 and t3 will not be moved, because they are not the BigObject's children.


Log in to reply
 

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