在我的 Qt5 程序中,我正在处理多个对象,并且需要花费大量时间和代码来禁用或更改 20 个复选框的状态。是否有任何选项可以制作一组复选框(或任何其他对象)并用一行对其执行命令?
例如:
QCheckBox b1, b2, b3, b4, b5;
QCheckBox_Group Box_1to5 = {b1, b2, b3, b4, b5};
ui->Box_1to5->setEnabled(false);
可能吗?
弗兰克的评论是您想要简单地启用/禁用一组小部件,但我将回答您更一般的问题,即如何将状态更改应用于一组对象。如果您可以自由使用 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);
});