Question

I am having problems with QTcpSocket, it’s not emitting any signals :/


void NetworkInstance::run()
{
    m_pSocket = new QTcpSocket();
    connect(m_pSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError()));
    connect(m_pSocket, SIGNAL(hostFound()), this, SLOT(socketHostLookupDone()));
    connect(m_pSocket, SIGNAL(connected()), this, SLOT(socketConnected()));
    connect(m_pSocket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));

    connect(m_pSocket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));

    QSettings s;
    s.beginGroup("network");
    emit log(QString("Connection to: ").append(s.value("host").toString()).append(":").append(s.value("port").toString()));
    m_pSocket->connectToHost(s.value("host").toString(), s.value("port").toInt());
    s.endGroup();

    exec();
}

This is my code, I don’t see any error in it, but non of the connected signal is emitting (hostFound, connected, etc.). On server I can see that connection is established and data sent, but nothing happens on client end. The NetworkInstance is extenting QThread.

Was it helpful?

Solution

Based on my earlier comment that subclassing QThread is wrong, what you need to do is create your class inherited from QObject and then move that to the new QThread.

So you'd have a class which looks something like this: -

class NetworkInstance : public QObject
{
    Q_OBJECT

public:
    NetworkInstance();

public slots:
    void Run();

    void socketConnected();
    void socketError();
    // etc for other slots...

private:
    class QTCPSocket* m_pSocket;
}

Create your Network instance object and thread: -

QThread* pThread = new QThread;
NetworkInstance* pNetworkInstance = new NetworkInstance;

Create the QTCPSocket instance and connect the signals / slots in your NetworkInstance class and then create the QThread and move your class to the thread: -

pNetworkInstance->moveToThread(pThread);

Finally, start the thread running: -

pThread->start();

OTHER TIPS

I am sure the signals are emitted. I am not so sure they are received by slots in another thread. Should be. Normally.

Qt::AutoConnection

(default) If the signal is emitted from a different thread than the receiving object, the signal is queued, behaving as Qt::QueuedConnection. Otherwise, the slot is invoked directly, behaving as Qt::DirectConnection. The type of connection is determined when the signal is emitted.

But now you start your own eventloop with exec() in run().

Edit: Ahh... I see...

Qt::QueuedConnection

The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.

That's what automatically is used since sender and receiver are in different threads. But with your 'exec()' the control never returns to the receiver's thread.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top