Search code examples
c++qtqthreadqt-signals

Slots and signals in QThread


I'm tryng to connect() a signal in thread 2 to slot in a main thread, I have constructor like that, which runs in thread 2 as a child class of QThread:

InputHandler::InputHandler()
{
    connect(this, SIGNAL(write(User*, Message)), TTCServer::ttcserver, SLOT(write(User*, Message)));
    qDebug() << "new thread created!";
}

but I get an runtime error

QObject::connect: No such signal QThread::write(User*, Message)

My inputhandler.h looks like that:

#ifndef INPUTHANDLER_H
#define INPUTHANDLER_H

#include <QThread>
#include <QDebug>
#include <QString>
#include "message.h"
#include "data.h"

class InputHandler : public QThread
{
public:
    InputHandler();
    void run();

private:
    Message message;
    void login(User* user, QString login);
    void sendLogins(User* user);
    void startGameWith(User* user, QString opponentLogin);

signals:
    void write(User* user, Message message);
};

#endif // INPUTHANDLER_H

And If it does matter, I'm also inncluding ttcserver.h:

#ifndef TTCSERVER_H
#define TTCSERVER_H

#include <QTcpServer>
#include <QObject>
#include <QDebug>
#include "data.h"
#include "user.h"
#include "message.h"
#include "inputhandler.h"

class TTCServer : public QTcpServer
{
    Q_OBJECT

public:
    explicit TTCServer();
    static TTCServer* ttcserver;
    void run();

signals:

public slots:
    void newConnection();
    void write(User* user, Message message);

 private:
    QTcpServer* server;
    Message* message;
    void handleInputFrom(User* user);

};

#endif

 // TTCSERVER_H

void write method is definied in ttcserver.cpp like that:

void TTCServer::write(User* user, Message message)
{
    qDebug() << "Signal recieved!";
}

So why write(User*, Message) in a connect() function tries to be QThread::write() instead of InputHandler::write()?

User and Message are classes, to be clear.


Solution

  • You forgot to add the Q_OBJECT macro into InputHandler:

    class InputHandler : public QThread
    {
        Q_OBJECT
    public:
        InputHandler();
        void run();
    <...>
    

    Since the macro is missing, moc will not create the corresponding code for signals/slots to work in that class, thus it tries to connect to QObject, since it does have the macro, and is the base class.