0

I'm trying to play with basic signal/slot in C++.

Here is my Network-Manager, which will trigger the event:

class NetworkManager : public QObject {
Q_OBJECT
public:
    explicit NetworkManager(QApplication* application);
    void OnFinished(QNetworkReply *reply);
    ...
signals:
    void OnReceived();
};

And in Display-Manager, this class will receive the event:

class DisplayManager : public QObject{
Q_OBJECT
public:
    explicit DisplayManager(QApplication *app);
    void ChangeWallPaper();
public slots:
    void ReceiveData();
};

And I'm trying to connect from another class:


Manager::Manager(QApplication *application, NetworkManager networkManager, DisplayManager displayManager)
: networkManager(application),displayManager(application) {
    ...
    connect(&networkManager, &NetworkManager::OnReceived, &displayManager, &DisplayManager::ReceiveData);
}

And in these class's implementation:

void DisplayManager::ReceiveData() {
    std::cout << "being called" << std::endl;// to check if this is being called
}

void NetworkManager::OnFinished(QNetworkReply *reply) {
    OnReceived(); // to trigger
}
// OnReceived() not implemented as it just a signal

What am I missing here? Why is the ReceiveData function not being called?

rgettman
  • 176,041
  • 30
  • 275
  • 357
Maifee Ul Asad
  • 3,992
  • 6
  • 38
  • 86

2 Answers2

3

Consider your Manager constructor...

Manager::Manager(QApplication *application,
                 NetworkManager networkManager,
                 DisplayManager displayManager)
    : networkManager(application)
    , displayManager(application)
{
    ...
    connect(&networkManager, &NetworkManager::OnReceived,
            &displayManager, &DisplayManager::ReceiveData);
}

You pass the addresses of locally scoped variables networkManager and displayManager to connect. The connection will be destroyed as soon as those temporary variables go out of scope when the constructor completes.

Try passing networkManager and displayManager either by reference or pointer.

G.M.
  • 12,232
  • 2
  • 15
  • 18
  • i'm passing them as pointer, and they don't work.. you have pasted my code, just doing some indentation – Maifee Ul Asad Feb 16 '21 at 18:21
  • Sorry but I don't understand your last comment. In the code you supplied the constructor for class `Manager` accepts a `NetworkManager` and a `DisplayManager` by *value*. Perhaps you could show the class definition for `Manager`. – G.M. Feb 16 '21 at 18:29
  • @MaifeeUlAsad Are you sure the code in your question is the *real* code? Looking at it again it shouldn't be possible to pass `NetworkManager` or `DisplayManager` by value if they inherit from `QObject`. – G.M. Feb 16 '21 at 18:41
  • yeah, this is **real code**. *your solution doesn't work*, **you've just copy pasted my code with indentation**. can you tell what's the difference between the code i posted and you did, except that indentation part ? – Maifee Ul Asad Feb 17 '21 at 05:57
  • 1
    I pasted you code into my answer to provide some context for what I thought was the problem. But, if the class definitions for `NetworkManager` and `DisplayManager` are as shown then I don't see how the `Manager` code provided can even compile. Again, please show the class definition for `Manager` and show how you are using it. Better still, provide a [mcve]. – G.M. Feb 17 '21 at 08:29
0

Here is the solution :

Manager::Manager(QApplication *application,
                 NetworkManager _networkManager,
                 DisplayManager _displayManager)
        : networkManager(application)
        , displayManager(application)
{
    ...
    connect(&networkManager, &NetworkManager::OnReceived,
            &displayManager, &DisplayManager::ReceiveData);
}
Maifee Ul Asad
  • 3,992
  • 6
  • 38
  • 86