组对象

时间:2015-12-06 15:43:57

标签: c++ qt c++11 qt5 qtwidgets

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

例如:

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

有可能吗?

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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/