c++qtqt5qt-signalsqt-slot

QT looking for slot in wrong class


I have a separate class for making a GET request with QNetwork shown below.

Reqest header:

#ifndef REQUEST_H
#define REQUEST_H

#include <QUrl>
#include <QObject>

class Request : public QObject
{
    Q_OBJECT

public:
    void make_request(QUrl url, const char* slot);
};

#endif // REQUEST_H

Request source:

#include "request.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>

void Request::make_request(const QUrl url, const char* slot)
{
    QNetworkAccessManager* manager = new QNetworkAccessManager();
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, slot);

    QNetworkReply* reply = manager->get(QNetworkRequest(url));
}

I ran this function in my MainWindow class by running the following.

request.make_request(QUrl("{ApiUrl}"), SLOT(parse_trending(QNetworkReply*)));

However, it produces the error QObject::connect: No such slot Request::parse_trending(QNetworkReply*) in {MainWindow}

I have the Q_OBJECT macro added to my header files, but I still do not know what is causing this error.

I will still provide my MainWindow header, perhaps the mistake is in there.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QNetworkReply>
#include <QObject>
#include "util/request.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    Request request;

public slots:
    void parse_trending(QNetworkReply *reply);
};

#endif // MAINWINDOW_H

Solution

  • In the following code:

    connect(manager, SIGNAL(finished(QNetworkReply*)), this, slot);
    

    You are pointing out that the slot belongs to this, that is, it belongs to Request but the slot belongs to MainWindow, so the solution is to pass the receiver as parameter:

    request.h

    ...
    void make_request(const QUrl & url, QObject *receiver, const char *slot);
    ...
    

    request.cpp

    void Request::make_request(const QUrl url, QObject *receiver, const char* slot)
    {
        QNetworkAccessManager* manager = new QNetworkAccessManager();
        connect(manager, SIGNAL(finished(QNetworkReply*)), receiver, slot);
        manager->get(QNetworkRequest(url));
    }
    

    and

    request.make_request(QUrl("{ApiUrl}"), this, SLOT(parse_trending(QNetworkReply*)));
    

    another option using std::function (#include <functional>):

    void Request::make_request(const QUrl & url, std::function<void (QNetworkReply *)> slot)
    {
        QNetworkAccessManager* manager = new QNetworkAccessManager();
        connect(manager, &QNetworkAccessManager::finished, slot);
        manager->get(QNetworkRequest(url));
    }
    

    request.make_request(QUrl("{ApiUrl}"), std::bind(&MainWindow::parse_trending, this, std::placeholders::_1));