Search code examples
c++qtc++11qt5qtwidgets

Group of objects


In my Qt5 program I'm working on multiple objects and it's taking a lot of time and code to disable or change state of 20 checkboxes. Is there any option to make a group of checkboxes (or any other objects) and perform commands on it with one line?

For instance:

QCheckBox b1, b2, b3, b4, b5;
QCheckBox_Group Box_1to5 = {b1, b2, b3, b4, b5};
ui->Box_1to5->setEnabled(false);

Is it possible?


Solution

  • Frank's comment is what you want for simply enabling/disabling a set of widgets, but I'll answer your more general question of how to apply a change of state to a set of objects. If you are free to use C++11, then the following will give you the general ability to call any member function on any object with a common set of function arguments:

    // Member functions without arguments
    template<typename ObjectPtrs, typename Func>
    void  batchApply(ObjectPtrs objects, Func func)
    {
        for (auto object : objects)
        {
            (object->*func)();
        }
    }
    
    // Member functions with 1 or more arguments
    template<typename ObjectPtrs, typename Func, typename ... Args>
    void  batchApply(ObjectPtrs objects, Func func, Args ... args)
    {
        for (auto object : objects)
        {
            (object->*func)(args ...);
        }
    }
    

    With the above, you can achieve your goal of being able to call a function on a set of objects with a single line of code. You would use it something like this:

    QCheckbox  b1, b2, b3, b4, b5;
    auto Box_1to5 = {b1, b2, b3, b4, b5};
    
    batchApply(Box_1to5, &QCheckbox::setChecked, false);
    batchApply(Box_1to5, &QCheckbox::toggle);
    

    The one limitation of the above method is that it doesn't handle default function arguments, so even if a function has a default argument, you have to explicitly provide one. For example, the following will result in a compiler error because animateClick has one argument (its default value is ignored):

    batchApply(Box_1to5, &QCheckbox::animateClick);
    

    The above technique uses variadic templates to support any number and type of function arguments. If you are not yet familiar with these, you may find the following useful:

    https://crascit.com/2015/03/21/practical-uses-for-variadic-templates/