Group of objects

Group of objects

本文关键字:objects of Group      更新时间:2023-10-16

在我的Qt5程序中,我正在处理多个对象,禁用或更改20个复选框的状态需要花费大量时间和代码。有没有任何选项可以制作一组复选框(或任何其他对象)并用一行对其执行命令?

例如:

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

有可能吗?

Frank的评论是您想要的简单启用/禁用一组小部件,但我将回答您关于如何将状态更改应用于一组对象的更一般的问题。如果您可以自由使用C++11,那么以下内容将使您能够使用一组通用的函数参数在任何对象上调用任何成员函数:

// 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 ...);
    }
}

通过以上操作,您可以实现用一行代码在一组对象上调用函数的目标。你可以这样使用它:

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

上述方法的一个限制是它不处理默认的函数参数,因此即使函数有默认参数,也必须显式提供一个。例如,以下情况将导致编译器错误,因为animateClick有一个参数(其默认值被忽略):

batchApply(Box_1to5, &QCheckbox::animateClick);

上述技术使用可变模板来支持任何数量和类型的函数参数。如果你还不熟悉这些,你可能会发现以下有用的:

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

您可以定义一个信号并将其连接到所有复选框:

/* In the constructor or at the start*/
QVector<QCheckbox*> boxes{b1, b2, b3, b4, b5};
for(QCheckbox* box: boxes) {
    connect(this, &MyWidget::setBoxCheckedState, box, &QCheckbox::setChecked); 
}
/* Somewhere in the code where the state should change */
emit setBoxCheckedState(true); // <- custom signal on your class

或者您可以使用for_each算法:

bool checked = true; 
std::for_each(boxes.begin(), boxes.end(), [checked](QCheckbox* box) { 
    box->setChecked(checked);
});