[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.



  • @Harry123

    Hello and welcome to devnet,

    from the Signals and Slots documentation you can take the following function:

    QObject::sender()

    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 :)



  • @onek24

    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.



  • @Harry123

    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.



  • @onek24

    A numeric identifier does work much better in a C++ switch command, and these numbers also have a useful meaning in my case.

    Thanks a lot for your help.



  • @Harry123

    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;
    


  • @onek24

    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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.