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. QTcpSocket in Thread
Forum Updated to NodeBB v4.3 + New Features

QTcpSocket in Thread

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 4 Posters 690 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.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by A Former User
    #1

    Hi I am developing a QML application. I am developing the backend with c++. I'm trying to establish a tcp connection in a thread and make it communicate in a way that doesn't block the QML application. My code is as below. It successfully connects to the server but does not send or receive messages. What is the problem here and how can I solve it? Can a new thread be created from a class in Thread?

    Output:

    QObject: Cannot create children for a parent that is in a different thread.
    (Parent is QTcpSocket(0x2c1f5724210), parent's thread is QThread(0x2c1f5724090), current thread is QThread(0x7ff7169ff030)
    QObject: Cannot create children for a parent that is in a different thread.
    (Parent is QTcpSocket(0x2c1f5724210), parent's thread is QThread(0x2c1f5724090), current thread is QThread(0x7ff7169ff030)
    

    // main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    #include "src/user.h"
    
    QThread userThread;
    User user;
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);    
    
        user.moveToThread(&userThread);
        QObject::connect(&userThread, &QThread::started, &user, &User::run);
        userThread.start();
    
        QQmlApplicationEngine engine;
        const QUrl url(u"qrc:/Make/Main.qml"_qs);
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
            &app, []() { QCoreApplication::exit(-1); },
            Qt::QueuedConnection);
        engine.load(url);
    
        return app.exec();
    }
    
    

    // user.h

    #ifndef USER_H
    #define USER_H
    
    #include <QObject>
    #include <QDebug>
    #include <QThread>
    #include <QTcpSocket>
    
    class User : public QObject
    {
        Q_OBJECT
    private:
        QTcpSocket *socket;
    public:
        explicit User(QObject *parent = nullptr);
    
    public slots:
        void run();
        void readSocket();
    
    signals:
    
    };
    
    #endif // USER_H
    
    

    // user.cpp

    #include "user.h"
    
    User::User(QObject *parent)
        : QObject{parent}
    {
        socket = new QTcpSocket();
        QObject::connect(socket, &QTcpSocket::readyRead, this, &User::readSocket);
    }
    
    void User::run()
    {
        for(;;) {
            if(!socket->isOpen()) {
                socket->connectToHost("127.0.0.1", 1337);
                if(socket->waitForConnected(3000)) {
                    QByteArray data("Hello");
                    socket->write(data);
                }
            }
    
            QThread::sleep(3000);
        }
    }
    
    void User::readSocket()
    {
        if(socket->isOpen()) {
            QByteArray data = socket->readAll();
            qDebug() << data.toStdString();
        }
    }
    
    Christian EhrlicherC 1 Reply Last reply
    0
    • ? A Former User

      Hi I am developing a QML application. I am developing the backend with c++. I'm trying to establish a tcp connection in a thread and make it communicate in a way that doesn't block the QML application. My code is as below. It successfully connects to the server but does not send or receive messages. What is the problem here and how can I solve it? Can a new thread be created from a class in Thread?

      Output:

      QObject: Cannot create children for a parent that is in a different thread.
      (Parent is QTcpSocket(0x2c1f5724210), parent's thread is QThread(0x2c1f5724090), current thread is QThread(0x7ff7169ff030)
      QObject: Cannot create children for a parent that is in a different thread.
      (Parent is QTcpSocket(0x2c1f5724210), parent's thread is QThread(0x2c1f5724090), current thread is QThread(0x7ff7169ff030)
      

      // main.cpp

      #include <QGuiApplication>
      #include <QQmlApplicationEngine>
      
      #include "src/user.h"
      
      QThread userThread;
      User user;
      
      int main(int argc, char *argv[])
      {
          QGuiApplication app(argc, argv);    
      
          user.moveToThread(&userThread);
          QObject::connect(&userThread, &QThread::started, &user, &User::run);
          userThread.start();
      
          QQmlApplicationEngine engine;
          const QUrl url(u"qrc:/Make/Main.qml"_qs);
          QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
              &app, []() { QCoreApplication::exit(-1); },
              Qt::QueuedConnection);
          engine.load(url);
      
          return app.exec();
      }
      
      

      // user.h

      #ifndef USER_H
      #define USER_H
      
      #include <QObject>
      #include <QDebug>
      #include <QThread>
      #include <QTcpSocket>
      
      class User : public QObject
      {
          Q_OBJECT
      private:
          QTcpSocket *socket;
      public:
          explicit User(QObject *parent = nullptr);
      
      public slots:
          void run();
          void readSocket();
      
      signals:
      
      };
      
      #endif // USER_H
      
      

      // user.cpp

      #include "user.h"
      
      User::User(QObject *parent)
          : QObject{parent}
      {
          socket = new QTcpSocket();
          QObject::connect(socket, &QTcpSocket::readyRead, this, &User::readSocket);
      }
      
      void User::run()
      {
          for(;;) {
              if(!socket->isOpen()) {
                  socket->connectToHost("127.0.0.1", 1337);
                  if(socket->waitForConnected(3000)) {
                      QByteArray data("Hello");
                      socket->write(data);
                  }
              }
      
              QThread::sleep(3000);
          }
      }
      
      void User::readSocket()
      {
          if(socket->isOpen()) {
              QByteArray data = socket->readAll();
              qDebug() << data.toStdString();
          }
      }
      
      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      You don't pass a parent to your QTcpSocket so moveToThread() doesn't/can't move it to the new thread since it only moves 'User' and it's children but your QTcpSocket is not a children of 'User'

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      ? 1 Reply Last reply
      1
      • Christian EhrlicherC Christian Ehrlicher

        You don't pass a parent to your QTcpSocket so moveToThread() doesn't/can't move it to the new thread since it only moves 'User' and it's children but your QTcpSocket is not a children of 'User'

        ? Offline
        ? Offline
        A Former User
        wrote on last edited by
        #3

        @Christian-Ehrlicher So what to do?

        J.HilkJ 1 Reply Last reply
        0
        • ? A Former User

          @Christian-Ehrlicher So what to do?

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

          @NullByte said in QTcpSocket in Thread:

          @Christian-Ehrlicher So what to do?

          consider not using threads at all.


          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.

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

            @NullByte said in QTcpSocket in Thread:

            @Christian-Ehrlicher So what to do?

            consider not using threads at all.

            jeremy_kJ Offline
            jeremy_kJ Offline
            jeremy_k
            wrote on last edited by
            #5

            @J-Hilk said in QTcpSocket in Thread:

            consider not using threads at all.

            For nearly every threading question on this forum (and almost every forum not concerned with high performance computing), this is the best answer.

            Asking a question about code? http://eel.is/iso-c++/testcase/

            ? 1 Reply Last reply
            1
            • jeremy_kJ jeremy_k

              @J-Hilk said in QTcpSocket in Thread:

              consider not using threads at all.

              For nearly every threading question on this forum (and almost every forum not concerned with high performance computing), this is the best answer.

              ? Offline
              ? Offline
              A Former User
              wrote on last edited by
              #6

              @jeremy_k How do we do this? Is it enough to use a Signal Slot?

              Christian EhrlicherC jeremy_kJ 2 Replies Last reply
              0
              • ? A Former User

                @jeremy_k How do we do this? Is it enough to use a Signal Slot?

                Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @NullByte said in QTcpSocket in Thread:

                Is it enough to use a Signal Slot?

                Why should it not? It's shown in the documentation and Qt uses signals and slots everywhere.

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                1 Reply Last reply
                0
                • System has marked this topic as solved on
                • ? A Former User

                  @jeremy_k How do we do this? Is it enough to use a Signal Slot?

                  jeremy_kJ Offline
                  jeremy_kJ Offline
                  jeremy_k
                  wrote on last edited by
                  #8

                  @NullByte said in QTcpSocket in Thread:

                  @jeremy_k How do we do this? Is it enough to use a Signal Slot?

                  1. Start with connecting signals to slots using automatic connections.
                  2. If that proves to be inadequate, profile the application to determine and quantify the issue.
                  3. If* the cause is unavoidable blocking calls or long sections of non-decomposable logic, consider a thread** to offload that section.

                  * There's always an exception
                  ** Read and understand the documentation related to QThread, QObject::moveToThread(), and in particular https://doc.qt.io/qt-6/qobject.html#thread-affinity . The error @Christian-Ehrlicher refers to has its own call-out:

                  Note: A QObject's member variables do not automatically become its children. The parent-child relationship must be set by either passing a pointer to the child's constructor, or by calling setParent(). Without this step, the object's member variables will remain in the old thread when moveToThread() is called.

                  Asking a question about code? http://eel.is/iso-c++/testcase/

                  1 Reply Last reply
                  2

                  • Login

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