Qt 4.8, connecting signals with slots
-
I have a number of different controls, I am trying to implement a generic mechanism for connecting signals to slots , in the configuration file I have a section:
[CONNECTIONS] "dial1","dialMoved(int)","lbl1","setText"
dial1 and lbl1 are unique IDs used to store the controls in a QMap.
dialMoved(int) is the signal and setText is the slot, however I'm using it at the moment as I would like to use a lamda slot to receive and handle the slot forwarding.Is there anyway to connect a signal and slot using the string name "dialMoved(int)", I have written a lambda class that I use elsewhere and this works fine, but so far my attempts to create a connecting are failing.
-
@SPlatten said in Qt 4.8, connecting signals with slots:
I see the output:
Object::connect: Use the SIGNAL macro to bind QDial::dialMoved(int)Ok my failure, I was a little too optimist.
As @Christian-Ehrlicher and @SGaist already says, you have to useQMetaObject
/QMetaMethod
to be able to do it.Here a small example:
#include <QObject> #include <QDebug> #include <QCoreApplication> #include <QTimer> #include <QMetaObject> #include <QMetaMethod> class ConnectTest : public QObject { Q_OBJECT public: explicit ConnectTest(QObject *parent = nullptr) : QObject{parent} { } public slots: void mySlots() { qDebug() << "ConnectTest"; } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); auto tmr = new QTimer(&a); tmr->setObjectName("myTimer"); auto cnxTest = new ConnectTest(&a); cnxTest->setObjectName("cnxTest"); QStringList lst; lst << "myTimer" << "timeout()" << "cnxTest" << "mySlots()"; auto src = a.findChild<QObject*>(lst[0]); if(!src) qDebug() << "src" << lst[0] <<"not found"; auto dest = a.findChild<QObject*>(lst[2]); if(!src) qDebug() << "dest" << lst[2] <<"not found"; // find the signal in the source instance int signal = src->metaObject()->indexOfSignal(lst[1].toLatin1().constData()); if(signal < 0) qDebug() << "signal" << lst[1] << "not found in" << lst[0]; // find the slot in the destination instance int slot = dest->metaObject()->indexOfSlot(lst[3].toLatin1().constData()); if(slot < 0) qDebug() << "slot" << lst[3] << "not found in" << lst[2]; // connect source and destination QObject::connect(src, src->metaObject()->method(signal), dest, dest->metaObject()->method(slot)); // start the timer tmr->start(5000); return a.exec(); }
-
@SPlatten said in Qt 4.8, connecting signals with slots:
Is there anyway to connect a signal and slot using the string name "dialMoved(int)", I have written a lambda class that I use elsewhere and this works fine, but so far my attempts to create a connecting are failing.
AFAIK,
connect()
accept aconst char *
for signal and slot.
So this should work:// I suppose all is in a QStringList cnxInfo // 0: src object name // 1: src object signal // 2: dest object name // 3: dest object slot // I suppose all items are childs of the class instance QObject * src = this->findChild<QObject *>(cnxInfo[0]); QObject * dest = this->findChild<QObject *>(cnxInfo[2]); QObject::connect(src, cnxInfo[1].toLatin1().constData(), dest, cnxInfo[3].toLatin1().constData());
-
@SPlatten said in Qt 4.8, connecting signals with slots:
dial1 and lbl1 are unique IDs used to store the controls in a QMap.
You cant have dynamic/variable variable names in C++...
So having a connection like
connect(map.key(), SIGNAL(.....), map.value(), SLOT(....));
wont work AFAIK, when you store
strings
in your map. -
@SPlatten said in Qt 4.8, connecting signals with slots:
thank you, still not quite right.
Don't understand what you mean with this?
Just to complete my previous reply: lambdas are not allowed/possible with Qt 4.x. It requires new
connect()
syntax which was introduced with Qt 5.x -
@KroMignon , sorry, can't you read minds ? ;)
I have tried:
QObject::connect(src, cnxInfo[1].toLatin1().constData(), dest, cnxInfo[3].toLatin1().constData());
Still returns false, also tried:
QObject::connect(pobjObject, SIGNAL(cstrSignalName), pobjSlotCtrl, SLOT(cstrSlotName));
Where pobjObject points to the signal source, cstrSignalName contains dialMoved(int), pobjSlotCtrl points the slot object and cstrSlotName contains setText(int).
Returns false too.
If I try:
QObject::connect(pobjObject, cstrSignalName.toLatin1().constData() ,pobjSlotCtrl, cstrSlotName.toLatin1().constData());
I see the output:
Object::connect: Use the SIGNAL macro to bind QDial::dialMoved(int)
-
@SPlatten said in Qt 4.8, connecting signals with slots:
Returns false too.
Wonder why this should work...
Hint: Take a look at the SIGNAL() and SLOT() macro - they're not no-ops.
-
@Pl45m4 said in Qt 4.8, connecting signals with slots:
You can connect QObjects, not strings
He's retrieving the QObjects via their objectName. This implies that they're properly set before.
-
Hi,
Beside the fact that you are trying to connect a signal with an int parameter to a slot with a QString parameter, if you really want to do that kind of generic connection, you should go with some meta programming. Use QMetaObject to retrieve the proper QMetaMethod objects for the signal and the slot and use them for the connection.
-
@SPlatten said in Qt 4.8, connecting signals with slots:
I see the output:
Object::connect: Use the SIGNAL macro to bind QDial::dialMoved(int)Ok my failure, I was a little too optimist.
As @Christian-Ehrlicher and @SGaist already says, you have to useQMetaObject
/QMetaMethod
to be able to do it.Here a small example:
#include <QObject> #include <QDebug> #include <QCoreApplication> #include <QTimer> #include <QMetaObject> #include <QMetaMethod> class ConnectTest : public QObject { Q_OBJECT public: explicit ConnectTest(QObject *parent = nullptr) : QObject{parent} { } public slots: void mySlots() { qDebug() << "ConnectTest"; } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); auto tmr = new QTimer(&a); tmr->setObjectName("myTimer"); auto cnxTest = new ConnectTest(&a); cnxTest->setObjectName("cnxTest"); QStringList lst; lst << "myTimer" << "timeout()" << "cnxTest" << "mySlots()"; auto src = a.findChild<QObject*>(lst[0]); if(!src) qDebug() << "src" << lst[0] <<"not found"; auto dest = a.findChild<QObject*>(lst[2]); if(!src) qDebug() << "dest" << lst[2] <<"not found"; // find the signal in the source instance int signal = src->metaObject()->indexOfSignal(lst[1].toLatin1().constData()); if(signal < 0) qDebug() << "signal" << lst[1] << "not found in" << lst[0]; // find the slot in the destination instance int slot = dest->metaObject()->indexOfSlot(lst[3].toLatin1().constData()); if(slot < 0) qDebug() << "slot" << lst[3] << "not found in" << lst[2]; // connect source and destination QObject::connect(src, src->metaObject()->method(signal), dest, dest->metaObject()->method(slot)); // start the timer tmr->start(5000); return a.exec(); }