[solved] Large menu - reduce number of required functions
-
I have a large menu and would like to limit the proliferation of functions in my class.
It would be much simpler in my case if I could connect all menu actions to one slot function that will handle them all. While connecting this way is entirely possible, I have not found how such a function could determine for which menu-action it was called. It would be nice if I could attach some numeric constant to each menu item, that I could recuperate within the called function.
I'm new to QT and have been researching the question, without finding a solution.
I was thinking about adding a QObject::event() override function to my main window, but have not found any event-type I could use that is relating to menus that are not context-menus. -
Hello and welcome to devnet,
from the Signals and Slots documentation you can take the following function:
Maybe this is what you are searching for :) You could, for example, cast to qobjects and compare against your menu actions to find the right action(the one which called your slot)
-
I think you might want to use QSignalMapper to transform each action into a single signal with a int / QString parameter.
-
@onek24 - Thanks, it's good to know that QObject::sender() exists.
@JohanSolo - QSignalMapper is probably the mechanism that best fits my needs.
-
@Harry123 said:
@onek24 - Thanks, it's good to know that QObject::sender() exists.
@JohanSolo - QSignalMapper is probably the mechanism that best fits my needs.
I'm glad you found a solution. Please tag this thread as solved as long as you don't have further questions. Thank you :)
-
Thinking about it again : I can define my own QAction class that contains my numeric identifier, connect all actions to the same slot function, and in it do qobject_cast() of QObject::sender() to my class.
This is a wonderfully economical solution - many thanks.
-
If your slot has access to your (list of) QActions then you could just compare your casted QObject::sender() to the equivalent QAction (from your list) instead of the identifier. Example (not tested but should work):
QAction buttonClick; if(qobject_cast<QAction*>(sender()) == &buttonClick) { // the sender was QAction buttonClick; }
You wouldn't need an custom action-class since your 'numeric identifier' in this case is the address of the object.
-
I'm glad that i could help you. :)
I don't know if there is something in c++11 for that, but anyone who wants to try could try the following:
QAction buttonClick; QAction exitClick; QAction *sender = qobject_cast<QAction*>(sender()); switch((int)sender) { case (int)(&buttonClick): // do something case (int)(&exitClick): // do something default: // no known qaction }
Haven't tried the code but it might work. I - for myself - don't like the idea of implementing a custom QAction class containing an identifier, therefore i'll just show the method above for everyone who might want to give it a try. The code above might only work assuming sizeof(int) == sizeof(QAction*) on the target platform.
Also it might be better to use
(intptr_t)action;
instead of
(int)action;
-
For the benefit of anyone finding this post, I found a much simpler solution for attaching information to a menu action :
void QAction::setData(const QVariant & userData) QVariant QAction::data() const
I currently prefer it over the much heavier solution of implementing a custom QAction class.
9/10