[SOLVED] Signals and slots as parameters
-
wrote on 24 Jan 2023, 15:29 last edited by Linhares
I'm trying to create a class that allows users to add objects of a particular type (derived from QObject) and connect them by using signal and slot names as parameters. Also, I want to insert all the objects in a list (or a QMap, as I did in the example below).
Here's an example of how users would do it:
addObject("object1", new MyObject(args)); addObject("object2", new MyObject(args)); addConnection("object1", "signal1", "object2", "slot1");
Here's what I've tried:
QMap<QString, QSharedPointer<MyObject>> objectsList; void MyClass::addObject(QString name, MyObject *object) { objectsList.insert(name, QSharedPointer<MyObject>(object)); } void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input) { connect(objectsList[obj1], output, objectsList[obj2], input); }
However, I get an error saying there's no known conversion from 'QSharedPointer<MyObject>' to 'const QObject *'.
My questions are:
- Is it correct to use QMap for the purpose of making a list of objects? In this case, is it necessary to use QSharedPointer?
- Does my idea for the addConnection function make any sense? How can I make it work?
-
I'm trying to create a class that allows users to add objects of a particular type (derived from QObject) and connect them by using signal and slot names as parameters. Also, I want to insert all the objects in a list (or a QMap, as I did in the example below).
Here's an example of how users would do it:
addObject("object1", new MyObject(args)); addObject("object2", new MyObject(args)); addConnection("object1", "signal1", "object2", "slot1");
Here's what I've tried:
QMap<QString, QSharedPointer<MyObject>> objectsList; void MyClass::addObject(QString name, MyObject *object) { objectsList.insert(name, QSharedPointer<MyObject>(object)); } void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input) { connect(objectsList[obj1], output, objectsList[obj2], input); }
However, I get an error saying there's no known conversion from 'QSharedPointer<MyObject>' to 'const QObject *'.
My questions are:
- Is it correct to use QMap for the purpose of making a list of objects? In this case, is it necessary to use QSharedPointer?
- Does my idea for the addConnection function make any sense? How can I make it work?
wrote on 24 Jan 2023, 15:33 last edited by JonB@Linhares said in Signals and slots as parameters:
However, I get an error saying there's no known conversion from 'QSharedPointer<MyObject>' to 'const QObject *'.
On what line?? The
connect()
?
I imagine the error message is as it says:no known conversion from 'QSharedPointer<MyObject>' to 'const QObject *'
, the latter being whatconnect()
accepts. What happens if you change theQMap
value's type toMyObject *
? -
I'm trying to create a class that allows users to add objects of a particular type (derived from QObject) and connect them by using signal and slot names as parameters. Also, I want to insert all the objects in a list (or a QMap, as I did in the example below).
Here's an example of how users would do it:
addObject("object1", new MyObject(args)); addObject("object2", new MyObject(args)); addConnection("object1", "signal1", "object2", "slot1");
Here's what I've tried:
QMap<QString, QSharedPointer<MyObject>> objectsList; void MyClass::addObject(QString name, MyObject *object) { objectsList.insert(name, QSharedPointer<MyObject>(object)); } void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input) { connect(objectsList[obj1], output, objectsList[obj2], input); }
However, I get an error saying there's no known conversion from 'QSharedPointer<MyObject>' to 'const QObject *'.
My questions are:
- Is it correct to use QMap for the purpose of making a list of objects? In this case, is it necessary to use QSharedPointer?
- Does my idea for the addConnection function make any sense? How can I make it work?
@Linhares said in Signals and slots as parameters:
QSharedPointer<MyObject>
Should be QSharedPointer<MyObject*> if MyObject is a QObject.
Also, you need to dereference the shared pointer to get the raw pointer for connect(). -
wrote on 24 Jan 2023, 16:07 last edited by
@JonB, yes, the message is on the
connect()
line.@jsulm, dereferencing the pointer seems to have worked (I hope I've done it right).
I'm strugling with the pointers though.
Here's how the code looks now:
QMap<QString, QSharedPointer<MyObject*>> objectsList; void MyClass::addObject(QString name, MyObject* object) { objectsList.insert(name, QSharedPointer<MyObject*>(object)); } void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input) { connect(*objectsList[obj1], output, *objectsList[obj2], input); }
I get this error on the
objectsList.insert()
line:
"No matching conversion for functional-style cast from 'MyObject *' to 'QSharedPointer<MyObject *>"How can I solve that?
-
@JonB, yes, the message is on the
connect()
line.@jsulm, dereferencing the pointer seems to have worked (I hope I've done it right).
I'm strugling with the pointers though.
Here's how the code looks now:
QMap<QString, QSharedPointer<MyObject*>> objectsList; void MyClass::addObject(QString name, MyObject* object) { objectsList.insert(name, QSharedPointer<MyObject*>(object)); } void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input) { connect(*objectsList[obj1], output, *objectsList[obj2], input); }
I get this error on the
objectsList.insert()
line:
"No matching conversion for functional-style cast from 'MyObject *' to 'QSharedPointer<MyObject *>"How can I solve that?
@Linhares said in Signals and slots as parameters:
objectsList.insert(name, QSharedPointer<MyObject*>(object));
objectsList.insert(name, QSharedPointer<MyObject>(object));
-
@jsulm , I've done that change and now I get an error message on the
connect()
line:
No known conversion from 'MyObject' to 'const QObject *'
wrote on 24 Jan 2023, 16:31 last edited by JonB@Linhares said in Signals and slots as parameters:
No known conversion from 'MyObject' to 'const QObject *'
Come on, show your actual line of code and the declaration/actual types of anything involved! The error message here tells you what is wrong.
If you still have
connect(*objectsList[obj1], output, *objectsList[obj2], input);
that will need changing if your
QMap
contains values which areQObject *
type, i.e.connect(objectsList[obj1], output, objectsList[obj2], input);
-
wrote on 24 Jan 2023, 16:47 last edited by Linhares
Here's how the code is now:
QMap<QString, QSharedPointer<MyObject>> objectsList; void MyClass::addObject(QString name, MyObject *object) { objectsList.insert(name, QSharedPointer<MyObject>(object)); //as suggested by @jsulm } void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input) { connect(*objectsList[obj1], output, *objectsList[obj2], input); //Error message: No known conversion from 'MyObject' to 'const QObject *' }
If I change the
connect()
line as per @JonB suggests, I get this:QMap<QString, QSharedPointer<MyObject>> objectsList; void MyClass::addObject(QString name, MyObject *object) { objectsList.insert(name, QSharedPointer<MyObject>(object)); } void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input) { connect(objectsList[obj1], output, objectsList[obj2], input); //Error message: No known conversion from 'QSharedPointer<MyObject>' to 'const QObject *' }
-
Here's how the code is now:
QMap<QString, QSharedPointer<MyObject>> objectsList; void MyClass::addObject(QString name, MyObject *object) { objectsList.insert(name, QSharedPointer<MyObject>(object)); //as suggested by @jsulm } void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input) { connect(*objectsList[obj1], output, *objectsList[obj2], input); //Error message: No known conversion from 'MyObject' to 'const QObject *' }
If I change the
connect()
line as per @JonB suggests, I get this:QMap<QString, QSharedPointer<MyObject>> objectsList; void MyClass::addObject(QString name, MyObject *object) { objectsList.insert(name, QSharedPointer<MyObject>(object)); } void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input) { connect(objectsList[obj1], output, objectsList[obj2], input); //Error message: No known conversion from 'QSharedPointer<MyObject>' to 'const QObject *' }
wrote on 24 Jan 2023, 16:49 last edited by@Linhares said in Signals and slots as parameters:
QMap<QString, QSharedPointer<MyObject>> objectsList;
Maybe I misunderstood, but I thought you had got rid of this
QSharedPointer
stuff? My suggestion was based on that understanding. -
wrote on 24 Jan 2023, 16:58 last edited by
@JonB, like this?
QMap<QString, MyObject *> objectsList; void MyClass::addObject(QString name, MyObject *object) { objectsList.insert(name, object); } void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input) { connect(objectsList[obj1], output, objectsList[obj2], input); }
Yes, it seems to be working!
Thank you so much! -
@JonB, like this?
QMap<QString, MyObject *> objectsList; void MyClass::addObject(QString name, MyObject *object) { objectsList.insert(name, object); } void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input) { connect(objectsList[obj1], output, objectsList[obj2], input); }
Yes, it seems to be working!
Thank you so much!wrote on 24 Jan 2023, 17:28 last edited by JonB@Linhares
That was indeed all I had in mind. Especially since you say you are "struggling" with pointers I think theQSharedPointer
just adds another layer you may not need. I think get it right with normal pointers to start with. -
wrote on 25 Jan 2023, 08:22 last edited by
It is somehow reasonable to use
QSharedPointer
here. Most of the time it is not a good idea to use raw pointers (in modern C++). Someone has to manage the memory. Most of the time it will just work in Qt because most of the time Qt objects have a parent which will handle deletion of children when destroyed. If those pointers only live because they are inside a container, the container should use a smart pointer (I'd preferstd::shared_ptr
overQSharedPointer
, but that's a different topic).There is an easy solution to the problem of connecting when using a shared pointer inside the map.
connect()
expects a raw pointer. For a smart pointer you get its raw pointer by callingget
, i.e.objectsList[obj1].get()
. This is the whole trick here.@Linhares said in [SOLVED] Signals and slots as parameters:
addConnection("object1", "signal1", "object2", "slot1");
This approach will not work immediately. Once you get your
connect()
to compile it will tell you at runtime that the signal and slot could not be found. Certainly, you have to use the old connect syntax. The string needs to include the argument types, like"signal1(int)"
or"slot1()"
. Or has that changed at some point?
1/12