[Solved] How can I know which slot cares about the signal I'm about to send?
-
@whereness I don't understand why you want to "communicate specifically with the object that made the request". It seems the signal/slot system you have is fine. I don't get why you want to make things more complex.
But anyway if I understand what you want you should do something like:
Make your request methods public slots.
Create request/post signals in your tables
Connect the signals to the appropriate slots
When they want data emit those signals then catch them:RestClient::requestSlot(WhateverObject object){ Table table = qobject_cast<Table>(sender()); // Do whatever }
-
@raf924 said:
@whereness I don't understand why you want to "communicate specifically with the object that made the request". It seems the signal/slot system you have is fine. I don't get why you want to make things more complex.
Say I have 2 employee model instances, one will query for employees at location 1, the other will query for employees at location 2. Each one will connect a slot to the REST client's employeeListReady(QList<Employee> &) signal and make their respective requests (i.e. they're unique instances of the same model class). The REST client will do its own signal/slot connections and make each request, then later when the replies signal finished(), it will parse each reply and dutifully signal with the list. Both models' slots are called for each reply. How do the models know which signal was meant for it's particular request? I can't have signals for each type of query (eg. location 1, location 2) because the UI allows user-specified queries (eg. location 1, lastname Smith). I could return the QNetworkReply pointer for each request, then the REST client would have to pass that along in it's signal to the models, then the models would have to keep track of them and check its reply object list to decide whether the signal was for them or not. But that seems messy. I'm thinking each model should have it's own REST client instance to avoid all of that, but that seems wasteful, as there will be many models and UI objects that will need to make REST requests. Seems like I'm missing something...
-
@whereness Don't use signals on the restclient side, do as i proposed:
@raf924 said:
Make your request methods public slots.
Create request/post signals in your tables
Connect the signals to the appropriate slots
When they want data emit those signals then catch them:RestClient::requestSlot(WhateverObject object){ Table table = qobject_cast<Table>(sender()); // Do whatever }
-
@raf924 said:
@whereness Don't use signals on the restclient side, do as i proposed:
@raf924 said:
Make your request methods public slots.
Create request/post signals in your tables
Connect the signals to the appropriate slots
When they want data emit those signals then catch them:RestClient::requestSlot(WhateverObject object){ Table table = qobject_cast<Table>(sender()); // Do whatever }
If I follow, you're proposing the table emit a signal when it wants data. The the restclient still needs to make the asynchronous request for data from the server, so unless I cache the table pointer on the restclient and associate it with the QNetworkReply pointer somehow, I still have the same problem. Maybe that goes with what you're suggesting? Unfortunately, there will be more than just that object type wanting to request data (eg. QTableModel derivatives), so the casting may get ugly. Maybe I'm still missing something. Thanks for your help BTW.
-
Hi,
One way to implement that is for the client to return an object doing the parsing of the QNetworkReply and emitting a signal when all is ready. So you can re-use your client singleton in multiple objects without the need of much intelligence in it. You can take a look at the qtenginio module for inspiration.
Hope it helps
-
@whereness When i say "tables" i mean the type that will emit the signal you can test which class to cast like this:
if (qobject_cast<TableModel>(sender()) != NULL) { /* yourobjectpointer is an instance of YourQClass which should be a QObject subclass */ }
or like this
if(sender()->metaObject()->className()=="TableModel")
Or try to have only one requester type which you subclass but that will require you to alter the architecture of your program i guess.
But yes the need to cache the table pointer goes away with my suggestion (that was the whole point of it) because it is retrieved with the sender method -
@raf924 said:
@whereness When i say "tables" i mean the type that will emit the signal you can test which class to cast like this:
if (qobject_cast<TableModel>(sender()) != NULL) { /* yourobjectpointer is an instance of YourQClass which should be a QObject subclass */ }
or like this
if(sender()->metaObject()->className()=="TableModel")
Or try to have only one requester type which you subclass but that will require you to alter the architecture of your program i guess.
But yes the need to cache the table pointer goes away with my suggestion (that was the whole point of it) because it is retrieved with the sender methodIt would still have to be cached in the restclient because the response from the webserver arrives asynchronously of the request for data.
-
@whereness Oh yeah my bad I was so focused on the part where you communicate with the objects i forgot about the actual web query. You can use this : http://doc.qt.io/qt-5/qnetworkrequest.html#setOriginatingObject
then get it back with this http://doc.qt.io/qt-5/qnetworkreply.html#request. -
@raf924 said:
@whereness Oh yeah my bad I was so focused on the part where you communicate with the objects i forgot about the actual web query. You can use this : http://doc.qt.io/qt-5/qnetworkrequest.html#setOriginatingObject
then get it back with this http://doc.qt.io/qt-5/qnetworkreply.html#request.Yes! Thanks!
-
@whereness You're welcome don't forget to add [SOLVED] to your topic title
-
@SGaist said:
Hi,
One way to implement that is for the client to return an object doing the parsing of the QNetworkReply and emitting a signal when all is ready. So you can re-use your client singleton in multiple objects without the need of much intelligence in it. You can take a look at the qtenginio module for inspiration.
Hope it helps
I ended up going this route, as how things were, this had less impact on existing code and seemed more straightforward API-wise. Thanks.