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: Cannot create children for a parent that is in a different thread

QObject: Cannot create children for a parent that is in a different thread

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 5 Posters 1.5k 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.
  • SPlattenS Offline
    SPlattenS Offline
    SPlatten
    wrote on last edited by SPlatten
    #1

    In my main application thread:

        ConnectionToTrainer* pConn(new ConnectionToTrainer(
                                       socketDescriptor, this));
        QObject::connect(pConn, &ConnectionToTrainer::tcpReceived,
                         this, &TcpBinaryReceiver::onTcpReceived);
        QObject::connect(qApp, &QCoreApplication::aboutToQuit,
                         pConn, &ConnectionToTrainer::quit);
        QObject::connect(pConn, &ConnectionToTrainer::finished,
                         pConn, &ConnectionToTrainer::deleteLater);
        pConn->start();
    

    The prototype for the class:

    class ConnectionToTrainer : public QThread
    {
        Q_OBJECT
     
    private:
        QFile* mpobjRxFile;
        QTcpSocket* mpsckCli;
        qintptr msckDescriptor;
        QTimer mtmrRxEnd;
        quint32 muint32PacketNo;
        quint64 muint64Received;
     
    public:
        static const quint16 mscuint16RxEndTimeout;
     
        explicit ConnectionToTrainer(qintptr ID, QObject* pParent = nullptr);
        void kick();
        void run();
     
    signals:
        void error(QTcpSocket::SocketError sckError);
        void tcpReceived(qintptr msckDescriptor, quint32 uint32PacketNo,
                         int intReceived);
     
    public slots:
        void disconnected();
        void readyRead();
    };
    

    And the implementation:

    ConnectionToTrainer::ConnectionToTrainer(qintptr ID, QObject* pParent)
        : QThread(pParent),
          mpobjRxFile(nullptr),
          mpsckCli(nullptr),
          msckDescriptor(ID),
          muint32PacketNo(0),
          muint64Received(0)
    {
        QObject::connect(&mtmrRxEnd, &QTimer::timeout,
            [this]()
            {
                if ( muint64Received > 0 )
                {
        //File received
                    DatasetTransfer* pobjTransfer(DatasetTransfer::pCurrentTransfer());
                    if ( pobjTransfer != nullptr )
                    {
                        QFile& rFile(pobjTransfer->rFile());
                        emit pobjTransfer->transferComplete(rFile.fileName());
                    }
                }
                mtmrRxEnd.stop();
            }
        );
    }
    

    At runtime I am seeing:

    QObject: Cannot create children for a parent that is in a different thread.
    (Parent is ConnectionToTrainer(0x11d2d38), parent's thread is QThread(0x118a718), current thread is ConnectionToTrainer(0x11d2d38)
    
    I'm not exactly sure what this is telling me or what the offending code is or how to resolve?
    

    Kind Regards,
    Sy

    KroMignonK 1 Reply Last reply
    0
    • JoeCFDJ Offline
      JoeCFDJ Offline
      JoeCFD
      wrote on last edited by JoeCFD
      #3

      use worker and move the thread into the worker. Do not use qthread directly.
      And send signal to the worker for creating children.
      https://wiki.qt.io/QThreads_general_usage

      1 Reply Last reply
      4
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by VRonin
        #2

        QThread is not the secondary thread, it's a wrapper around it. only QThread::run is the secondary thread. slots of QThread will be run in the main thread. see https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        4
        • JoeCFDJ Offline
          JoeCFDJ Offline
          JoeCFD
          wrote on last edited by JoeCFD
          #3

          use worker and move the thread into the worker. Do not use qthread directly.
          And send signal to the worker for creating children.
          https://wiki.qt.io/QThreads_general_usage

          1 Reply Last reply
          4
          • SPlattenS SPlatten

            In my main application thread:

                ConnectionToTrainer* pConn(new ConnectionToTrainer(
                                               socketDescriptor, this));
                QObject::connect(pConn, &ConnectionToTrainer::tcpReceived,
                                 this, &TcpBinaryReceiver::onTcpReceived);
                QObject::connect(qApp, &QCoreApplication::aboutToQuit,
                                 pConn, &ConnectionToTrainer::quit);
                QObject::connect(pConn, &ConnectionToTrainer::finished,
                                 pConn, &ConnectionToTrainer::deleteLater);
                pConn->start();
            

            The prototype for the class:

            class ConnectionToTrainer : public QThread
            {
                Q_OBJECT
             
            private:
                QFile* mpobjRxFile;
                QTcpSocket* mpsckCli;
                qintptr msckDescriptor;
                QTimer mtmrRxEnd;
                quint32 muint32PacketNo;
                quint64 muint64Received;
             
            public:
                static const quint16 mscuint16RxEndTimeout;
             
                explicit ConnectionToTrainer(qintptr ID, QObject* pParent = nullptr);
                void kick();
                void run();
             
            signals:
                void error(QTcpSocket::SocketError sckError);
                void tcpReceived(qintptr msckDescriptor, quint32 uint32PacketNo,
                                 int intReceived);
             
            public slots:
                void disconnected();
                void readyRead();
            };
            

            And the implementation:

            ConnectionToTrainer::ConnectionToTrainer(qintptr ID, QObject* pParent)
                : QThread(pParent),
                  mpobjRxFile(nullptr),
                  mpsckCli(nullptr),
                  msckDescriptor(ID),
                  muint32PacketNo(0),
                  muint64Received(0)
            {
                QObject::connect(&mtmrRxEnd, &QTimer::timeout,
                    [this]()
                    {
                        if ( muint64Received > 0 )
                        {
                //File received
                            DatasetTransfer* pobjTransfer(DatasetTransfer::pCurrentTransfer());
                            if ( pobjTransfer != nullptr )
                            {
                                QFile& rFile(pobjTransfer->rFile());
                                emit pobjTransfer->transferComplete(rFile.fileName());
                            }
                        }
                        mtmrRxEnd.stop();
                    }
                );
            }
            

            At runtime I am seeing:

            QObject: Cannot create children for a parent that is in a different thread.
            (Parent is ConnectionToTrainer(0x11d2d38), parent's thread is QThread(0x118a718), current thread is ConnectionToTrainer(0x11d2d38)
            
            I'm not exactly sure what this is telling me or what the offending code is or how to resolve?
            
            KroMignonK Offline
            KroMignonK Offline
            KroMignon
            wrote on last edited by KroMignon
            #4

            @SPlatten said in QObject: Cannot create children for a parent that is in a different thread:

            At runtime I am seeing:
            QObject: Cannot create children for a parent that is in a different thread.
            (Parent is ConnectionToTrainer(0x11d2d38), parent's thread is QThread(0x118a718), current thread is ConnectionToTrainer(0x11d2d38)

            I'm not exactly sure what this is telling me or what the offending code is or how to resolve?

            Once again you done same mistake.
            QThread is a QObject based class which contains/manage a thread.
            The instance of QThread 'lives' in the thread in which it was created, which is not the same as the contained thread!

            So please avoid to sub-class QThread if you want to use it with QObjects and/or signals/slots and use a worker class which you moves to the dedicated thread.

            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

            SPlattenS 1 Reply Last reply
            5
            • KroMignonK KroMignon

              @SPlatten said in QObject: Cannot create children for a parent that is in a different thread:

              At runtime I am seeing:
              QObject: Cannot create children for a parent that is in a different thread.
              (Parent is ConnectionToTrainer(0x11d2d38), parent's thread is QThread(0x118a718), current thread is ConnectionToTrainer(0x11d2d38)

              I'm not exactly sure what this is telling me or what the offending code is or how to resolve?

              Once again you done same mistake.
              QThread is a QObject based class which contains/manage a thread.
              The instance of QThread 'lives' in the thread in which it was created, which is not the same as the contained thread!

              So please avoid to sub-class QThread if you want to use it with QObjects and/or signals/slots and use a worker class which you moves to the dedicated thread.

              SPlattenS Offline
              SPlattenS Offline
              SPlatten
              wrote on last edited by
              #5

              @KroMignon , there are plenty of examples:

              https://doc.qt.io/qt-5/qtnetwork-threadedfortuneserver-example.html

              That show using QThread in the same way I have.

              Kind Regards,
              Sy

              KroMignonK 1 Reply Last reply
              0
              • SPlattenS SPlatten

                @KroMignon , there are plenty of examples:

                https://doc.qt.io/qt-5/qtnetwork-threadedfortuneserver-example.html

                That show using QThread in the same way I have.

                KroMignonK Offline
                KroMignonK Offline
                KroMignon
                wrote on last edited by KroMignon
                #6

                @SPlatten said in QObject: Cannot create children for a parent that is in a different thread:

                That show using QThread in the same way I have.

                No really as you are doing.
                Is this example, QThread::run() is overriding and all QObject based instances are created there. So they are all living in the holded thread.
                Your are creating a QTimer within ConnectionToTrainer constructor, so this timer is living the same thread which have be used to create ConnectionToTrainer instance. Which is, obviously, not the same as the managed thread.

                It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                SPlattenS 1 Reply Last reply
                1
                • KroMignonK KroMignon

                  @SPlatten said in QObject: Cannot create children for a parent that is in a different thread:

                  That show using QThread in the same way I have.

                  No really as you are doing.
                  Is this example, QThread::run() is overriding and all QObject based instances are created there. So they are all living in the holded thread.
                  Your are creating a QTimer within ConnectionToTrainer constructor, so this timer is living the same thread which have be used to create ConnectionToTrainer instance. Which is, obviously, not the same as the managed thread.

                  SPlattenS Offline
                  SPlattenS Offline
                  SPlatten
                  wrote on last edited by
                  #7

                  @KroMignon , I'll try to describe the problem.

                  I have an application 'server' that is the focal point for other 'client' applications. The server uses UDP to communicate with all clients notifying them that content is ready.

                  Once a client receives the broadcast via UDP it sends a request to the server for the content. The content is then sent via TCP. I have a thread that creates a TCP connection to the client and sends the file over TCP, what I want to do is get the client to wait until the file transfer completes. I use a timer in the client to determine when the data flow from the server has ended. The server sends binary data and in some cases this can be over 1GB.

                  In the client class that receives the TCP data I have a thread that updates the GUI whilst the transfer is in progress. So I have modified the run function to loop whilst the timer isActive, what do I need to do in the loop to ensure that application functions correct, what is the correct way to satisfy this ?

                  Kind Regards,
                  Sy

                  KroMignonK J.HilkJ 2 Replies Last reply
                  0
                  • SPlattenS SPlatten

                    @KroMignon , I'll try to describe the problem.

                    I have an application 'server' that is the focal point for other 'client' applications. The server uses UDP to communicate with all clients notifying them that content is ready.

                    Once a client receives the broadcast via UDP it sends a request to the server for the content. The content is then sent via TCP. I have a thread that creates a TCP connection to the client and sends the file over TCP, what I want to do is get the client to wait until the file transfer completes. I use a timer in the client to determine when the data flow from the server has ended. The server sends binary data and in some cases this can be over 1GB.

                    In the client class that receives the TCP data I have a thread that updates the GUI whilst the transfer is in progress. So I have modified the run function to loop whilst the timer isActive, what do I need to do in the loop to ensure that application functions correct, what is the correct way to satisfy this ?

                    KroMignonK Offline
                    KroMignonK Offline
                    KroMignon
                    wrote on last edited by KroMignon
                    #8

                    @SPlatten said in QObject: Cannot create children for a parent that is in a different thread:

                    what is the correct way to satisfy this ?

                    I am not a C++/Qt expert, so I avoid to do "fancy stuff".
                    I am always using QObject based worker classes to handle the task I have to do. When multi-threading is required, I don't have to change anything in my code, only have to add a moveToThread() call to use a dedicated thread for this task.
                    Of course, there are some rules to follow:

                    • all children must have base instance as parent to "follow" the parent in the new thread or create all children instances in a kind of "start()" function which is called from the new thread (as described here: https://wiki.qt.io/QThreads_general_usage)
                    • use signals and slots to communicate with outside to avoid threading issues and let Qt handle this for you (I am lazy!)

                    So based on this, I would create a worker class which handles the socket and emits a signal to notify about transfer progression (eg. progress(int prct)). And use this signal to update the GUI.

                    It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                    1 Reply Last reply
                    0
                    • SPlattenS SPlatten

                      @KroMignon , I'll try to describe the problem.

                      I have an application 'server' that is the focal point for other 'client' applications. The server uses UDP to communicate with all clients notifying them that content is ready.

                      Once a client receives the broadcast via UDP it sends a request to the server for the content. The content is then sent via TCP. I have a thread that creates a TCP connection to the client and sends the file over TCP, what I want to do is get the client to wait until the file transfer completes. I use a timer in the client to determine when the data flow from the server has ended. The server sends binary data and in some cases this can be over 1GB.

                      In the client class that receives the TCP data I have a thread that updates the GUI whilst the transfer is in progress. So I have modified the run function to loop whilst the timer isActive, what do I need to do in the loop to ensure that application functions correct, what is the correct way to satisfy this ?

                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #9

                      @SPlatten said in QObject: Cannot create children for a parent that is in a different thread:

                      what is the correct way to satisfy this

                      why don't you tell the receiver via UDP that the transfer is done. instead of an arbitrary waiting time?


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      SPlattenS 1 Reply Last reply
                      1
                      • J.HilkJ J.Hilk

                        @SPlatten said in QObject: Cannot create children for a parent that is in a different thread:

                        what is the correct way to satisfy this

                        why don't you tell the receiver via UDP that the transfer is done. instead of an arbitrary waiting time?

                        SPlattenS Offline
                        SPlattenS Offline
                        SPlatten
                        wrote on last edited by SPlatten
                        #10

                        @J-Hilk , thank you, I will give that a go, although the UDP goes to all clients.

                        Kind Regards,
                        Sy

                        J.HilkJ 1 Reply Last reply
                        0
                        • SPlattenS SPlatten

                          @J-Hilk , thank you, I will give that a go, although the UDP goes to all clients.

                          J.HilkJ Offline
                          J.HilkJ Offline
                          J.Hilk
                          Moderators
                          wrote on last edited by
                          #11

                          @SPlatten said in QObject: Cannot create children for a parent that is in a different thread:

                          @J-Hilk , thank you, I will give that a go, although the UDP goes to all clients.

                          I know, I usually have an ID - byte at the front of my UDP datagrams, that identifies it as a Datagram for all or for a specific recipient


                          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                          Q: What's that?
                          A: It's blue light.
                          Q: What does it do?
                          A: It turns blue.

                          1 Reply Last reply
                          0

                          • Login

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