Unsolved Getting QMetaMethod of slot member function to connect "later"
-
Hi. I have a class that I want to use as a container to hold the receiver and the slot method of a class. So that later the first class instance will pass as a parameter to a function that will make the final connect, using whatever sender and signal to the stored receiver and slot. I am not sure how could I store the address of a member method (a slot) from a class to a QMetaMethod object to later use the overload connect method.
At the moment I am managing to do so by making the class to be a templated class, but then the signature gets a little weird to pass the parameters, and I would simplify it as the connect method from QObject.
Thanks a lot!
Regards,
David.
-
Hi and welcome to devnet,
Can you show some pseudo code to explain what you would like to achieve ?
-
I want to refactor from THIS:
class ManageUserWorkflow : public QObject { Q_OBJECT; enum WorkflowStep { WS_STEP_1, WS_STEP_2, WS_STEP_3 } enum Action { A_OK, A_CANCEL, A_RETRY } public: ManageUserWorkflow(){}; public slot: void ActionHandler(){ // do Handle code } FooterController* createFooter(const QList<Action>& actions) { FooterController* fc = new FooterController(); for( int i = 0; i < actionList.size(); ++i) { Button* b = new Button(actions.at(i)); connect(button, &Button::clicked, this, &ManageUserWorkflow::ActionHandler); fc->addButton(b); } } DialogController* createDialog(WorkflowStep step) { QList<Action> actions; switch( step ) { case WS_STEP_1: { dialog = new DialogController("A"); actions << A_OK; break; } case WS_STEP_2: { dialog = new DialogController("B"); actions << A_OK; actions << A_CANCEL; break; } case WS_STEP_2: { dialog = new DialogController("C"); actions << A_RETRY; actions << A_CANCEL; break; } } FooterController footer = new FooterController(actions); dialog->setFooter( footer ); } }
to THIS:
class WorkflowDialogCreator : public QObject { Q_OBJECT; public: WorkflowDialogCreator(){}; FooterController* createFooter(const QList<Action>& actions, const QList<QPair<QObject*, QMetaMethod*>> actionHandlers) { FooterController* fc = new FooterController(); for( int i = 0; i < actionList.size(); ++i) { Button* b = new Button(actions.at(i)); connect(button, &Button::clicked, actionHandlers.at(i).first, actionHandlers.at(i).first.second); fc->addButton(b); } } } class ManageUserWorkflow : public QObject Q_OBJECT; enum WorkflowStep { WS_STEP_1, WS_STEP_2, WS_STEP_3 } enum Action { A_OK, A_CANCEL, A_RETRY } public: ManageUserWorkflow(WorkflowDialogCreator* dc) : dc_(dc){}; public slot: void ActionHandler(){ // do Handle code } FooterController* createFooter(const QList<Action>& actions) { FooterController* fc = new FooterController(); for( int i = 0; i < actionList.size(); ++i) { Button* b = new Button(actions.at(i)); connect(button, &Button::clicked, this, &ManageUserWorkflow::ActionHandler); fc->addButton(b); } } DialogController* createDialog(WorkflowStep step) { QList<Action> actions; QList<QPair<QObject*, QMetaMethod*>> actionHandlers switch( step ) { case WS_STEP_1: { dialog = new DialogController("A"); actions << A_OK; actionHandlers << QPair(this, &ManageUserWorkflow::ActionHandler); break; } case WS_STEP_2: { dialog = new DialogController("B"); actions << A_OK; actions << A_CANCEL; actionHandlers << QPair(this, &ManageUserWorkflow::ActionHandler); actionHandlers << QPair(this, &ManageUserWorkflow::ActionHandler); break; } case WS_STEP_2: { dialog = new DialogController("C"); actions << A_RETRY; actions << A_CANCEL; actionHandlers << QPair(this, &ManageUserWorkflow::ActionHandler); actionHandlers << QPair(this, &ManageUserWorkflow::ActionHandler); break; } } FooterController footer = dc_.createFooter(actions, actionHandlers); dialog->setFooter( footer ); } WorkflowDialogCreator* dc_; }
Please forget constant correctness and other things. I made it fast in purpose. Also take into account this is a simplification of what the real code is.
-
The most similar solution of what I think I need found it here:
https://stackoverflow.com/questions/31836199/how-to-store-qt-signal-slot-names-to-a-data-structure