Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Confusing error using TcpSocket in a thread
Forum Update on Monday, May 27th 2025

Confusing error using TcpSocket in a thread

Scheduled Pinned Locked Moved Solved Qt for Python
7 Posts 3 Posters 620 Views
  • 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.
  • H Offline
    H Offline
    HenryInUtah
    wrote on 13 Jan 2024, 00:29 last edited by
    #1

    Hello,
    I am making a program that will communicate with a robot controller via a TCP socket. I need to have the socket work in a different thread so that the GUI stays responsive. The thread should send signals back to the GUI when something interesting happens.

    I ~thought~ that I was doing this correctly but I keep getting an error that I do not understand. I created a minimal example that also has the same error. Instead of pasting hundreds of lines of code, I put them on DropBox where they can be downloaded at this link:
    [link text]https://www.dropbox.com/scl/fo/n38a6xgw6thf1grj9vzuv/h?rlkey=av21gvdrwe9j5y3bw0pvns8vq&dl=0(link url)

    If there is another way that people on this forum like to get files please let me know.

    It probably won't make much sense without looking at the program, but here is the error about "Cannot create children for a parent that is in a different thread".

    ![alt text]https://www.dropbox.com/scl/fi/s2duclk7z441oeavbw4xm/Minimum-Example-Error-Message.png?rlkey=31e28yemgqwtn8avd6fwq2wmo&dl=0(image url)

    Thank you so much for your help.
    Henry

    J 1 Reply Last reply 13 Jan 2024, 01:11
    0
    • H HenryInUtah
      15 Jan 2024, 16:01

      Hello,

      I believe that connecting to the controller in a thread is necessary because the controller uses a ring buffer for positions and I have no idea when it will be sending messages to the GUI. It is not a case of traditional send & receive when the GUI wants to.

      Here is a better effort at a minimal example:

      import sys
      from PySide2.QtCore import Qt, QObject, QThread, Signal
      from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton
      from PySide2 import QtNetwork
      
      class MainWindow(QMainWindow):
      	def __init__(self):
      		super().__init__()
      
      		self.button = QPushButton('Connect')
      		self.setCentralWidget(self.button)
      		self.button.clicked.connect(self.button_Clicked)
      		self.Client = ClientThread()
      
      	def button_Clicked(self):
      		print('Clicked')
      		self.Client.start()
      
      class Communicate(QObject):
      	IncommingMessage = Signal(str)
      	TheCurrentState = Signal(str)
      
      class ClientThread(QThread):
      
      	def __init__(self, parent=None):
      		QThread.__init__(self, parent)
      		self.Signal = Communicate()
      		self.Socket = QtNetwork.QTcpSocket()
      		#self.Socket.readyRead.connect(self.readMessage)
      		#self.Socket.stateChanged.connect(self.stateChanged)
      
      	def readMessage(self):
      		Data = self.Socket.readAll()
      		self.Signal.IncommingMessage.emit(Data)
      
      	def run(self):
      		try:
      			self.Socket.connectToHost('127.0.0.1', 7777)
      		except Exception as Err:
      			print(Err)
      
      	def sendMessage(self, Message):
      		self.Socket.write(bytes(Message))
      
      	def stateChanged(self, NewSocketState):
      		self.SocketState = str(self.Socket.state())
      		self.Signal.TheCurrentState.emit(self.SocketState)
      
      app = QApplication(sys.argv)
      window = MainWindow()
      window.show()
      app.exec_()
      

      This is the error message when pressing the button. I don't understand why asking the QTcpSocket to connect to a host is creating children - and if it is, why isn't that happening in the thread. I'm very confused...

      Clicked
      QObject: Cannot create children for a parent that is in a different thread.
      (Parent is QTcpSocket(0x1d1bab69680), parent's thread is QThread(0x1d1baacbc30), current thread is ClientThread(0x1d1ba8feb80)
      QObject: Cannot create children for a parent that is in a different thread.
      (Parent is QTcpSocket(0x1d1bab69680), parent's thread is QThread(0x1d1baacbc30), current thread is ClientThread(0x1d1ba8feb80)
      
      J Offline
      J Offline
      jeremy_k
      wrote on 15 Jan 2024, 23:20 last edited by jeremy_k
      #5

      @HenryInUtah said in Confusing error using TcpSocket in a thread:

      Hello,

      I believe that connecting to the controller in a thread is necessary because the controller uses a ring buffer for positions and I have no idea when it will be sending messages to the GUI. It is not a case of traditional send & receive when the GUI wants to.

      Keyboard and mouse press events can also happen spontaneously. The event loop is designed to handle these. Socket notifier events from incoming network traffic also fit in this paradigm. Look at some of the server examples, such as the fortune server

      Here is a better effort at a minimal example:

      As an API thing, I suggest following the convention used by Qt and Python. Symbols beginning with an uppercase letter are a type. Use a lowercase symbol to indicate an instance. self.socket, not self.Socket.

      class ClientThread(QThread):
      
      	def __init__(self, parent=None):
      		QThread.__init__(self, parent)
      		self.Signal = Communicate()
      		self.Socket = QtNetwork.QTcpSocket()
      
      	def run(self):
      		try:
      			self.Socket.connectToHost('127.0.0.1', 7777)
      

      self.Socket() is allocated in the GUI thread, where ClientThread.__init__() is executing. That means that the socket's thread affinity is the GUI thread. ClientThread.run() executes in the ClientThread thread, leading to the reported mismatch.

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

      H 1 Reply Last reply 22 Jan 2024, 03:10
      2
      • H HenryInUtah
        13 Jan 2024, 00:29

        Hello,
        I am making a program that will communicate with a robot controller via a TCP socket. I need to have the socket work in a different thread so that the GUI stays responsive. The thread should send signals back to the GUI when something interesting happens.

        I ~thought~ that I was doing this correctly but I keep getting an error that I do not understand. I created a minimal example that also has the same error. Instead of pasting hundreds of lines of code, I put them on DropBox where they can be downloaded at this link:
        [link text]https://www.dropbox.com/scl/fo/n38a6xgw6thf1grj9vzuv/h?rlkey=av21gvdrwe9j5y3bw0pvns8vq&dl=0(link url)

        If there is another way that people on this forum like to get files please let me know.

        It probably won't make much sense without looking at the program, but here is the error about "Cannot create children for a parent that is in a different thread".

        ![alt text]https://www.dropbox.com/scl/fi/s2duclk7z441oeavbw4xm/Minimum-Example-Error-Message.png?rlkey=31e28yemgqwtn8avd6fwq2wmo&dl=0(image url)

        Thank you so much for your help.
        Henry

        J Offline
        J Offline
        jeremy_k
        wrote on 13 Jan 2024, 01:11 last edited by
        #2

        @HenryInUtah said in Confusing error using TcpSocket in a thread:

        Hello,
        I am making a program that will communicate with a robot controller via a TCP socket. I need to have the socket work in a different thread so that the GUI stays responsive. The thread should send signals back to the GUI when something interesting happens.

        This is a common mistake among programmers who are new to Qt or asynchronous programming. Try using the non-blocking APIs.

        I ~thought~ that I was doing this correctly but I keep getting an error that I do not understand. I created a minimal example that also has the same error. Instead of pasting hundreds of lines of code, I put them on DropBox where they can be downloaded at this link:

        If the minimal example involves hundreds of lines of code, something is wrong. Are you using a well known protocol?

        It probably won't make much sense without looking at the program, but here is the error about "Cannot create children for a parent that is in a different thread".

        That message is created when myObject->thread() != QThread::currentThread(). For example:

        QObject *o1 = new QObject;
        QThread thread;
        o1->moveToThread(&thread);
        QObject *o2 = new QObject(o1); // Cannot create children...
        

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

        H 1 Reply Last reply 15 Jan 2024, 16:01
        3
        • J jeremy_k
          13 Jan 2024, 01:11

          @HenryInUtah said in Confusing error using TcpSocket in a thread:

          Hello,
          I am making a program that will communicate with a robot controller via a TCP socket. I need to have the socket work in a different thread so that the GUI stays responsive. The thread should send signals back to the GUI when something interesting happens.

          This is a common mistake among programmers who are new to Qt or asynchronous programming. Try using the non-blocking APIs.

          I ~thought~ that I was doing this correctly but I keep getting an error that I do not understand. I created a minimal example that also has the same error. Instead of pasting hundreds of lines of code, I put them on DropBox where they can be downloaded at this link:

          If the minimal example involves hundreds of lines of code, something is wrong. Are you using a well known protocol?

          It probably won't make much sense without looking at the program, but here is the error about "Cannot create children for a parent that is in a different thread".

          That message is created when myObject->thread() != QThread::currentThread(). For example:

          QObject *o1 = new QObject;
          QThread thread;
          o1->moveToThread(&thread);
          QObject *o2 = new QObject(o1); // Cannot create children...
          
          H Offline
          H Offline
          HenryInUtah
          wrote on 15 Jan 2024, 16:01 last edited by
          #3

          Hello,

          I believe that connecting to the controller in a thread is necessary because the controller uses a ring buffer for positions and I have no idea when it will be sending messages to the GUI. It is not a case of traditional send & receive when the GUI wants to.

          Here is a better effort at a minimal example:

          import sys
          from PySide2.QtCore import Qt, QObject, QThread, Signal
          from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton
          from PySide2 import QtNetwork
          
          class MainWindow(QMainWindow):
          	def __init__(self):
          		super().__init__()
          
          		self.button = QPushButton('Connect')
          		self.setCentralWidget(self.button)
          		self.button.clicked.connect(self.button_Clicked)
          		self.Client = ClientThread()
          
          	def button_Clicked(self):
          		print('Clicked')
          		self.Client.start()
          
          class Communicate(QObject):
          	IncommingMessage = Signal(str)
          	TheCurrentState = Signal(str)
          
          class ClientThread(QThread):
          
          	def __init__(self, parent=None):
          		QThread.__init__(self, parent)
          		self.Signal = Communicate()
          		self.Socket = QtNetwork.QTcpSocket()
          		#self.Socket.readyRead.connect(self.readMessage)
          		#self.Socket.stateChanged.connect(self.stateChanged)
          
          	def readMessage(self):
          		Data = self.Socket.readAll()
          		self.Signal.IncommingMessage.emit(Data)
          
          	def run(self):
          		try:
          			self.Socket.connectToHost('127.0.0.1', 7777)
          		except Exception as Err:
          			print(Err)
          
          	def sendMessage(self, Message):
          		self.Socket.write(bytes(Message))
          
          	def stateChanged(self, NewSocketState):
          		self.SocketState = str(self.Socket.state())
          		self.Signal.TheCurrentState.emit(self.SocketState)
          
          app = QApplication(sys.argv)
          window = MainWindow()
          window.show()
          app.exec_()
          

          This is the error message when pressing the button. I don't understand why asking the QTcpSocket to connect to a host is creating children - and if it is, why isn't that happening in the thread. I'm very confused...

          Clicked
          QObject: Cannot create children for a parent that is in a different thread.
          (Parent is QTcpSocket(0x1d1bab69680), parent's thread is QThread(0x1d1baacbc30), current thread is ClientThread(0x1d1ba8feb80)
          QObject: Cannot create children for a parent that is in a different thread.
          (Parent is QTcpSocket(0x1d1bab69680), parent's thread is QThread(0x1d1baacbc30), current thread is ClientThread(0x1d1ba8feb80)
          
          J J 2 Replies Last reply 15 Jan 2024, 16:42
          0
          • H HenryInUtah
            15 Jan 2024, 16:01

            Hello,

            I believe that connecting to the controller in a thread is necessary because the controller uses a ring buffer for positions and I have no idea when it will be sending messages to the GUI. It is not a case of traditional send & receive when the GUI wants to.

            Here is a better effort at a minimal example:

            import sys
            from PySide2.QtCore import Qt, QObject, QThread, Signal
            from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton
            from PySide2 import QtNetwork
            
            class MainWindow(QMainWindow):
            	def __init__(self):
            		super().__init__()
            
            		self.button = QPushButton('Connect')
            		self.setCentralWidget(self.button)
            		self.button.clicked.connect(self.button_Clicked)
            		self.Client = ClientThread()
            
            	def button_Clicked(self):
            		print('Clicked')
            		self.Client.start()
            
            class Communicate(QObject):
            	IncommingMessage = Signal(str)
            	TheCurrentState = Signal(str)
            
            class ClientThread(QThread):
            
            	def __init__(self, parent=None):
            		QThread.__init__(self, parent)
            		self.Signal = Communicate()
            		self.Socket = QtNetwork.QTcpSocket()
            		#self.Socket.readyRead.connect(self.readMessage)
            		#self.Socket.stateChanged.connect(self.stateChanged)
            
            	def readMessage(self):
            		Data = self.Socket.readAll()
            		self.Signal.IncommingMessage.emit(Data)
            
            	def run(self):
            		try:
            			self.Socket.connectToHost('127.0.0.1', 7777)
            		except Exception as Err:
            			print(Err)
            
            	def sendMessage(self, Message):
            		self.Socket.write(bytes(Message))
            
            	def stateChanged(self, NewSocketState):
            		self.SocketState = str(self.Socket.state())
            		self.Signal.TheCurrentState.emit(self.SocketState)
            
            app = QApplication(sys.argv)
            window = MainWindow()
            window.show()
            app.exec_()
            

            This is the error message when pressing the button. I don't understand why asking the QTcpSocket to connect to a host is creating children - and if it is, why isn't that happening in the thread. I'm very confused...

            Clicked
            QObject: Cannot create children for a parent that is in a different thread.
            (Parent is QTcpSocket(0x1d1bab69680), parent's thread is QThread(0x1d1baacbc30), current thread is ClientThread(0x1d1ba8feb80)
            QObject: Cannot create children for a parent that is in a different thread.
            (Parent is QTcpSocket(0x1d1bab69680), parent's thread is QThread(0x1d1baacbc30), current thread is ClientThread(0x1d1ba8feb80)
            
            J Offline
            J Offline
            JonB
            wrote on 15 Jan 2024, 16:42 last edited by
            #4

            @HenryInUtah
            You have a threading problem, as @jeremy_k indicated. I think you have to do something about moving the QTcpSocket to the thread where you are servicing it, which you have not done. Before going any further, why do you need any QThread at all? Every time people do they often have these problems and it's not necessary anyway.

            Even if you do, see also https://doc.qt.io/qtforpython-6/PySide6/QtCore/QThread.html#detailed-description for the suggested WorkerThread approach.

            1 Reply Last reply
            1
            • H HenryInUtah
              15 Jan 2024, 16:01

              Hello,

              I believe that connecting to the controller in a thread is necessary because the controller uses a ring buffer for positions and I have no idea when it will be sending messages to the GUI. It is not a case of traditional send & receive when the GUI wants to.

              Here is a better effort at a minimal example:

              import sys
              from PySide2.QtCore import Qt, QObject, QThread, Signal
              from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton
              from PySide2 import QtNetwork
              
              class MainWindow(QMainWindow):
              	def __init__(self):
              		super().__init__()
              
              		self.button = QPushButton('Connect')
              		self.setCentralWidget(self.button)
              		self.button.clicked.connect(self.button_Clicked)
              		self.Client = ClientThread()
              
              	def button_Clicked(self):
              		print('Clicked')
              		self.Client.start()
              
              class Communicate(QObject):
              	IncommingMessage = Signal(str)
              	TheCurrentState = Signal(str)
              
              class ClientThread(QThread):
              
              	def __init__(self, parent=None):
              		QThread.__init__(self, parent)
              		self.Signal = Communicate()
              		self.Socket = QtNetwork.QTcpSocket()
              		#self.Socket.readyRead.connect(self.readMessage)
              		#self.Socket.stateChanged.connect(self.stateChanged)
              
              	def readMessage(self):
              		Data = self.Socket.readAll()
              		self.Signal.IncommingMessage.emit(Data)
              
              	def run(self):
              		try:
              			self.Socket.connectToHost('127.0.0.1', 7777)
              		except Exception as Err:
              			print(Err)
              
              	def sendMessage(self, Message):
              		self.Socket.write(bytes(Message))
              
              	def stateChanged(self, NewSocketState):
              		self.SocketState = str(self.Socket.state())
              		self.Signal.TheCurrentState.emit(self.SocketState)
              
              app = QApplication(sys.argv)
              window = MainWindow()
              window.show()
              app.exec_()
              

              This is the error message when pressing the button. I don't understand why asking the QTcpSocket to connect to a host is creating children - and if it is, why isn't that happening in the thread. I'm very confused...

              Clicked
              QObject: Cannot create children for a parent that is in a different thread.
              (Parent is QTcpSocket(0x1d1bab69680), parent's thread is QThread(0x1d1baacbc30), current thread is ClientThread(0x1d1ba8feb80)
              QObject: Cannot create children for a parent that is in a different thread.
              (Parent is QTcpSocket(0x1d1bab69680), parent's thread is QThread(0x1d1baacbc30), current thread is ClientThread(0x1d1ba8feb80)
              
              J Offline
              J Offline
              jeremy_k
              wrote on 15 Jan 2024, 23:20 last edited by jeremy_k
              #5

              @HenryInUtah said in Confusing error using TcpSocket in a thread:

              Hello,

              I believe that connecting to the controller in a thread is necessary because the controller uses a ring buffer for positions and I have no idea when it will be sending messages to the GUI. It is not a case of traditional send & receive when the GUI wants to.

              Keyboard and mouse press events can also happen spontaneously. The event loop is designed to handle these. Socket notifier events from incoming network traffic also fit in this paradigm. Look at some of the server examples, such as the fortune server

              Here is a better effort at a minimal example:

              As an API thing, I suggest following the convention used by Qt and Python. Symbols beginning with an uppercase letter are a type. Use a lowercase symbol to indicate an instance. self.socket, not self.Socket.

              class ClientThread(QThread):
              
              	def __init__(self, parent=None):
              		QThread.__init__(self, parent)
              		self.Signal = Communicate()
              		self.Socket = QtNetwork.QTcpSocket()
              
              	def run(self):
              		try:
              			self.Socket.connectToHost('127.0.0.1', 7777)
              

              self.Socket() is allocated in the GUI thread, where ClientThread.__init__() is executing. That means that the socket's thread affinity is the GUI thread. ClientThread.run() executes in the ClientThread thread, leading to the reported mismatch.

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

              H 1 Reply Last reply 22 Jan 2024, 03:10
              2
              • J jeremy_k
                15 Jan 2024, 23:20

                @HenryInUtah said in Confusing error using TcpSocket in a thread:

                Hello,

                I believe that connecting to the controller in a thread is necessary because the controller uses a ring buffer for positions and I have no idea when it will be sending messages to the GUI. It is not a case of traditional send & receive when the GUI wants to.

                Keyboard and mouse press events can also happen spontaneously. The event loop is designed to handle these. Socket notifier events from incoming network traffic also fit in this paradigm. Look at some of the server examples, such as the fortune server

                Here is a better effort at a minimal example:

                As an API thing, I suggest following the convention used by Qt and Python. Symbols beginning with an uppercase letter are a type. Use a lowercase symbol to indicate an instance. self.socket, not self.Socket.

                class ClientThread(QThread):
                
                	def __init__(self, parent=None):
                		QThread.__init__(self, parent)
                		self.Signal = Communicate()
                		self.Socket = QtNetwork.QTcpSocket()
                
                	def run(self):
                		try:
                			self.Socket.connectToHost('127.0.0.1', 7777)
                

                self.Socket() is allocated in the GUI thread, where ClientThread.__init__() is executing. That means that the socket's thread affinity is the GUI thread. ClientThread.run() executes in the ClientThread thread, leading to the reported mismatch.

                H Offline
                H Offline
                HenryInUtah
                wrote on 22 Jan 2024, 03:10 last edited by
                #6

                @jeremy_k
                Sorry for the delay...
                You are correct about the similarity to mouse and keyboard events. I'll move the socket object into the GUI class and see how it goes.

                I wish that I could follow examples such as the fortune server. Unfortunately, Qt thinks it is OK for document Python with C++ examples. I guess the assumption is that everyone that knows Python also knows C++.

                Cheers,
                Henry

                J 1 Reply Last reply 22 Jan 2024, 06:00
                0
                • H HenryInUtah
                  22 Jan 2024, 03:10

                  @jeremy_k
                  Sorry for the delay...
                  You are correct about the similarity to mouse and keyboard events. I'll move the socket object into the GUI class and see how it goes.

                  I wish that I could follow examples such as the fortune server. Unfortunately, Qt thinks it is OK for document Python with C++ examples. I guess the assumption is that everyone that knows Python also knows C++.

                  Cheers,
                  Henry

                  J Offline
                  J Offline
                  jeremy_k
                  wrote on 22 Jan 2024, 06:00 last edited by jeremy_k
                  #7

                  @HenryInUtah said in Confusing error using TcpSocket in a thread:

                  I wish that I could follow examples such as the fortune server. Unfortunately, Qt thinks it is OK for document Python with C++ examples. I guess the assumption is that everyone that knows Python also knows C++.

                  I'm pretty familiar with C++, and still run into the same problem from time to time.

                  https://code.qt.io/cgit/pyside/examples.git/ appears to be some and possibly all of the Qt core examples translated into PySide-flavored python. I glanced at the fortune server example. It doesn't have the depth of explanation that the C++ version presents.

                  Direct link: https://code.qt.io/cgit/pyside/examples.git/tree/examples/network/fortuneserver.py

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

                  1 Reply Last reply
                  0
                  • H HenryInUtah has marked this topic as solved on 22 Jan 2024, 16:49

                  2/7

                  13 Jan 2024, 01:11

                  5 unread
                  • Login

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