Creating a dynamic slot in Qt
A continuation of andref's code so as to use any member function as a slot
class SlotForwarder : public QObject
{
Q_OBJECT
public:
typedef void (*Function)();
SlotForwarder(Function function, QObject* parent = 0)
: QObject(parent)
, m_fptr(function)
{}
public slots:
void forward()
{
m_fptr();
}
private:
Function m_fptr;
};
int main(){
QApplication a(argc, argv);
MyClass myClassObject; //contains a function called MemberFunc
//create a slotforwarder object so
SlotForwarder *memberFuncSlot = new SlotForwarder (std::tr1::bind(&MyClass::MemberFunc, &myClassObject));
QObject::connect(ui.button,SIGNAL(clicked()),memberFuncSlot,SLOT(forward());
}
It does make a lot of sense. I assume QSignalMapper
is not what you want. If your functions don't have arguments, maybe something like this is enough:
class SlotForwarder : public QObject
{
Q_OBJECT
public:
typedef void (*Function)(); // or whatever. I never get this syntax right...
SlotForwarder(Function function, QObject* parent = 0)
: QObject(parent)
, m_fptr(function)
{}
public slots:
void forward()
{
m_fptr();
}
private:
Function m_fptr;
};
Create one for each function you want to encapsulate and connect to the forward
as usual.
Now, if they do have arguments, maybe this Qt Quarterly article might be of assistance.
Dynamic Signals and Slots by Eskil A. Blomfeldt
The technique involves reimplementing the qt_metacall
method yourself. The method has this signature:
int QObject::qt_metacall(QMetaObject::Call call, int id, void **arguments)
Call is the kind of metacall: slot, signal, property read or write, etc. Every slot has an id. The parameters are packed (by value or as pointers) inside the arguments array. Reading the code that the moc generates is a good way to understand how it all works.
Data about raw function signatures is available only during compile time, but slots are resolved at runtime. Because of that mismatch, you will need to wrap the functions into a template adapter type that presents a constant interface to your implementation of qt_metacall
and converts the arguments
array into something the function can understand (cf. Python unpack operator). Boost.Signals does that kind of template hackery.