3
votes

I use a QTcpSocket in a dedicated thread. For close this thread, I have a personal slot connected with the disconnected signal of the QTcpSocket. This slot contains the socket.close() instruction.

class Network
{
   private:

      QTcpSocket *mp_Socket;

   public:

      void connection()
      {
         mp_Socket = new QTcpSocket(this);

         // Move to thread

         connect(mp_Socket, SIGNAL(disconnected()), this, SLOT(disconnect()));
      }

   public slots:

      void disconnect()
      {
         mp_Socket->close();
      }
};

Here, the slot works (even if the socket is in another thread). But if I call the disconnect slot by myself, i have the following error :

"QSocketNotifier: socket notifiers cannot be disabled from another thread".

Why?

Thanks for your help. ;)

1
Have you tried to emit a signal from the other thread?gengisdave
Socket operations by members of the socket is closed. Chained to an external data conditions. Makes it difficult to back off pursuit operations.dsgdfg
I tried to emit a signal as QTcpSocket with disconnected signal but I have same error.Maluna34

1 Answers

2
votes

Ok, so you may need to change your design a little. Instead of moving only the socket to a new thread, make your Network class Object derived, and move it instead, and have the socket parented to it. My previous answer revision did not work because close() was not registered with the Qt meta system, because it is a plain virtual function, not a slot. With the new design you can have interthread signals and slots which will solve the problem. Connections between objects in different threads will automatically be resolved as queued and use the event loop to schedule execution in the correct thread.

Also, I notice you have a slot in your current class, without it being QObject derived. That will not work, you need Qt's meta system to have slots. You don't get an error, because slots compiles to nothing in C++, it is only used by the MOC (meta object compiler), so you don't really have a slot.

Naturally, this means that QMetaObject::invokeMethod(yourNetworkClass, "disconnect", Qt::QueuedConnection) will now also work.