[SOLVED] Signals and slots as parameters
-
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:
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 *
? -
@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(). -
@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));
-
@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);
-
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 *' }
-
@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! -
-
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?