I work with the library for the game engine, there is a need to use the functionality of QtNetwork in this library. Actually connected all this business through heading files, libraries (Qt5Core and Qt5Network), and also added generation of moc files for heading files with Q_OBJECT macro.

Created a simple class with the Q_OBJECT macro

 #ifndef _Network_H_ #define _Network_H_ #include <QObject> #include <QTcpSocket> class CNetwork : public QObject { Q_OBJECT public: explicit CNetwork(QObject *parent = 0); public: void ConnectToServer(); public slots: void onConnectedToServer(); void onReadyRead(); void onBytesWritten(qint64 bytes); void onDisconnected(); private: bool connected; QTcpSocket* m_socket; }; #endif 

Implementation:

 #include "StdAfx.h" #include "Network.h" #include "Global.h" CNetwork::CNetwork(QObject *parent) : QObject(parent) { } void CNetwork::ConnectToServer() { Log(TITLE "connecting..."); int port = 3322; m_socket = new QTcpSocket(this); m_socket->connectToHost("127.0.0.1", port); connect(m_socket, &QTcpSocket::connected, this, &CNetwork::onConnectedToServer); connect(m_socket, &QTcpSocket::readyRead, this, &CNetwork::onReadyRead); connect(m_socket, &QTcpSocket::bytesWritten, this, &CNetwork::onBytesWritten); connect(m_socket, &QTcpSocket::disconnected, this, &CNetwork::onDisconnected); } void CNetwork::onConnectedToServer() { Log(TITLE "connected"); connected = true; } void CNetwork::onReadyRead() { Log(TITLE "readyRead"); } void CNetwork::onBytesWritten(qint64 bytes) { Log(TITLE "bytesWriten"); } void CNetwork::onDisconnected() { Log(TITLE "disconnected"); connected = false; } 

The whole thing is perfectly compiled and even connects to the server when you call ConnectToServer() . But signals and slots refuse to work. I think the thing is in the event loop , I tried to run the whole thing in a separate thread and created my own event loop :

 QEventLoop* m_loop = new QEventLoop(); m_loop->exec(); 

But it did not help. In general, the question is how to make the signals and slots work in this case?

  • one
    You need to use the QApplication instance, which starts the event handling. - Pavel Parshin
  • Thanks, it really helped! - AfroStalin

1 answer 1

The solution is to create an instance of QCoreApplication and run the event loop 'a.

The working code looks like this:

 #ifndef _Network_H_ #define _Network_H_ #include <QObject> #include <QTcpSocket> class CNetwork : public QObject { Q_OBJECT public: explicit CNetwork(QObject *parent = 0); public slots: void onConnectedToServer(); void onReadyRead(); void onBytesWritten(qint64 bytes); void onDisconnected(); private: bool connected; QTcpSocket* m_socket; public: void StartNetwork(); }; #endif 

Implementation:

 #include "StdAfx.h" #include "Network.h" #include <QCoreApplication> CNetwork::CNetwork(QObject *parent) : QObject(parent) { } void CNetwork::StartNetwork() { int argc = 0; char* argv[1] = {}; QCoreApplication networker(argc, argv); Log(TITLE "Connecting to server..."); int port = 3322; m_socket = new QTcpSocket(this); m_socket->connectToHost("127.0.0.1", port); connect(m_socket, &QTcpSocket::connected, this, &CNetwork::onConnectedToServer); connect(m_socket, &QTcpSocket::readyRead, this, &CNetwork::onReadyRead); connect(m_socket, &QTcpSocket::bytesWritten, this, &CNetwork::onBytesWritten); connect(m_socket, &QTcpSocket::disconnected, this, &CNetwork::onDisconnected); networker.exec(); } void CNetwork::onConnectedToServer() { Log(TITLE "connected"); connected = true; } void CNetwork::onReadyRead() { Log(TITLE "readyRead"); } void CNetwork::onBytesWritten(qint64 bytes) { Log(TITLE "bytesWriten"); } void CNetwork::onDisconnected() { Log(TITLE "disconnected"); connected = false; } 

You can use it like this - create a stream in which to create an instance of our class and start StartNetwork() . Example:

 #include "Network.h" #include <thread> void RunNetwork() { CNetwork pNetwork; pNetwork.StartNetwork(); } void CClass::ConnectToServer() { std::thread nerworkThread(RunNetwork); nerworkThread.detach(); } 

Thank you for solving the problem to Pavel Parshin.