PDA

View Full Version : QSignalMapper One single Object



cafu1007
12th March 2011, 17:51
Hi there,

Is it possible to connect different signals form the same object to a signalmapper, and still know wich signal is triggered? or there is a way to connect signal to a single slot wit a define input.

first case(did not work):


//signal1 and signal2 are cons char *
//firs case:
connect(object,signal1, sMapper,SLOT(map()));
sMapper->setMapping(object, signal1);
connect(object,signal2, sMapper,SLOT(map()));
sMapper->setMapping(object, signal2);

connect(sMapper, SIGNAL(mapped(QString)), this, SLOT(triggered(QString)));

//second case(What i would like to do):
//assign a predefined value to the signal.

connect(object,signal1, this,SLOT(triggered(=signal1)));
connect(object,signal2, this,SLOT(triggered(=signal2));



thanks for the answer

squidge
12th March 2011, 20:07
It's possible to have multiple signals coming to the same slot if they have the same signatures, but I don't think it's possible to detect which signal caused your slot to be called, only which object caused your signal be called.

Your second case would always fail at the connect, as the SIGNAL and SLOT signatures must match exactly.

Zlatomir
12th March 2011, 20:27
I imagine that you want two (or more) signals to trigger an action (do almost the same thing) and each of them can do some more stuff, that can be achieved with the help of an "helper" function - a function can do the things that are common for all the slots and you code a slot for each signal (with proper connection) and in the slot body do the signal-specific things and then call the helper function (that does the stuff common to all the slots).

//if i didn't guess the "design" than please say more about what you are trying to do, and than we can share opinions about that.

cafu1007
13th March 2011, 13:35
Hi There,

What I want is to implement is signal waiter, i have done this already but i don't think is the best way though, but so far is working. I have just create and "helper object", connect the signal that i want to track to the helper object slot, and then trigger a signal with helper object as parameter, then i can track which signal was triggered, but i think for many signal the overhead is to big, is a waste of memory, since i have to store the object that i want to track and the object that track the signal, if anybody have a better idea just let me know, thank for the help.


It's possible to have multiple signals coming to the same slot if they have the same signatures, but I don't think it's possible to detect which signal caused your slot to be called, only which object caused your signal be called.

Your second case would always fail at the connect, as the SIGNAL and SLOT signatures must match exactly.

thanks, i am aware of this situation.


I imagine that you want two (or more) signals to trigger an action (do almost the same thing) and each of them can do some more stuff, that can be achieved with the help of an "helper" function - a function can do the things that are common for all the slots and you code a slot for each signal (with proper connection) and in the slot body do the signal-specific things and then call the helper function (that does the stuff common to all the slots).

//if i didn't guess the "design" than please say more about what you are trying to do, and than we can share opinions about that.

i just want to track the signals

wysota
13th March 2011, 18:04
What exactly do you mean by "track signals"?

wysota
13th March 2011, 20:46
Anyway, try this:

#include <QtGui>


class SignalTracker : public QObject {
int qt_metacall(QMetaObject::Call call, int id, void **args) {
id = QObject::qt_metacall(call, id, args);
if(id==-1 || call != QMetaObject::InvokeMetaMethod)
return id;
if(!m_slots.contains(id)) return -1;
Signal sig = m_slots.value(id);
qDebug() << "Object:" << sig.source->objectName() << "signal:" << sig.signal;
return -1;
}
public:
SignalTracker(QObject *parent = 0) : QObject(parent) {
m_slotId = 0;
}
bool connectSignal(QObject *obj, const char *signal) {
QByteArray theSignal = QMetaObject::normalizedSignature(signal);
int signalId = obj->metaObject()->indexOfSignal(theSignal);
if(signalId == -1) {
return false;
}
m_slots[++m_slotId] = Signal(obj, theSignal);
QMetaObject::connect(obj, signalId, this, QObject::metaObject()->methodCount()+m_slotId);
return true;
}
private:
int m_slotId;
struct Signal {
QObject *source;
QByteArray signal;
Signal(QObject *src, const QByteArray &ba) : source(src), signal(ba){}
Signal() : source(0){}
};
QHash<int,Signal> m_slots;
};

int main(int argc, char **argv){
QApplication app(argc, argv);
SignalTracker tracker;
QPushButton button("Click me");
button.setObjectName("some button");
tracker.connectSignal(&button, "clicked()");
button.show();
QLineEdit le;
le.setObjectName("some line edit");
tracker.connectSignal(&le, "textChanged(const QString &)");
le.show();
return app.exec();
};

cafu1007
15th March 2011, 17:59
What exactly do you mean by "track signals"?
Hi wysota,
what i meanby that is: know when different signal from different or the same object have been triggered to count then or to wait for all of then before doing something, i have no tried yet the example. i let you know when i have.

Thanks for the help.

minirop
18th April 2011, 08:46
I've just made a class doing this (https://github.com/minirop/SignalsSpy). It tracks every signals from the object you want to monitor. You can just test the parameter of the emitted (or emittedNameOnly) signal to check only the ones you want. ;)