QAction with multiple widgets
-
I am trying to figure out the best/easiest way to implement the action pattern with multiple widgets using it. I have two questions:
- How to best implement focus-based "switch" for the widgets when the action is triggered? I have some ideas:
-
Have a slot that picks the widget with focus and calls its appropriate method.
-
Have a check for focus in all widget's methods connected to actions with return in case it does not have focus.
-
Disconnect/connect widgets as they get/lose focus.
The first solution is not very portable nor easily extend-able and it also requires casting in order to use correct method from QList<QWidget*> QAction::associatedWidgets() const... The second means the signal/slot call simply will happen for all widgets but the action will be taken only by the one with focus. This is easy to do but constly imho... And the last one is a chore because in case the action is connected to other stuff there is need to track the relevant connection to disconnect them (as opposed to simple mass disconnect). But I tend to think that is actually the best solution of these three.
Or maybe there is another?
- The action is not always relevant in given context. For example if there is a "Copy" action for the QTableView then it is not relevant when the current index is invalid. This is easy to solve by disabling the action with one widget but with multiple? Options I see:
-
Check if the action is valid in its slot
-
Disable/enable QAction appropriately when context changes
First option does not indicate to the user the action may not be taken (that it will do nothing) while the second option might be tricky to get right with multiple widgets all notifying like that. But that could be probably solved by disconecting/connecting these to only currently active widget...
What are your thoughts or practice you use?
-
Hi,
Are you thinking of something like Qt Creator's action handling ?
-
I believe so though I am unaware what pattern it follows. Can you point me to the right direction? Thanks.
-
You can take a look at the Qt Creator sources for ActionManager. The class seem to be doing at least some of your needs
-
Thanks, I stumbled upon it before but was unsure as whether it's the right thing. :-) I see what the approach is about with the ActionManager and I will likely mimic some of it. However I am still a bit fuzzy on how the QAction is supposed to be used under these circumstances. Basically it can be used as:
-
Have front-end QAction objects (in the menu connected to widgets directly via a manager). This approach requires the manager to know at least something about the widgets it connects to.
-
Have front-end QAction objects and back-end QAction object per widget so that the manager only pairs front-end action and back-end action based on context (i.e. the focus).
I like the second idea but in my mind the QAction is supposed to be re-usable so having many QActions all over just don't seem right to me. But from what I understand Qt Creator's ActionManager works like that.
-
-
It's not that you have many QAction all over. Each widget provide the set of actions it supports which means that you can build the front-end set of QAction based on your widgets content. Flexibility comes at a cost. However trying to have one fixed set of QAction that you'll reuse also means that your widgets will have to follow a given pattern or that you'll have to write a subscription based management where you widgets tell the action manager which slot should be connected to which action. It also means that if you want to add a new action because of a new widget, you'll have to update more code.