使用 Qt 表单中按顺序命名的 ui 个对象填充数组
Populating array with sequentially named ui objects from Qt form
我有一个 Qt 项目,其中 ui 在 Qt Designer 中创建。 ui 当前包含 16 个 QLabel。我需要一个包含所有 QLabel 的数组。目前我初始化数组:
labels_ = {ui->label0, ui->label1, ui->label2, ui->label3, ui->label4,
ui->label5, ui->label6, ui->label7, ui->label8, ui->label9,
ui->label10, ui->label11, ui->label12, ui->label13, ui->label14,
ui->label15};
我希望以后能够轻松地向 ui 表单添加和删除 QLabel。如果在某个时候我想用 100 个 QLabel 测试程序怎么办?
我发现 Boost.preprocessor 我可以做到这一点:
#define NLABELS 16
#define FILL_ARRAY(z, idx, name) \
BOOST_PP_CAT(name, idx),
labels_ = {BOOST_PP_REPEAT(NLABELS, FILL_ARRAY, ui->label)};
但是,我仍然在犹豫这是否是正确的做法。也许 Qt 有一些其他功能来实现这一点?
对我来说似乎是正确的,Qt 没有这方面的功能。
为什么不使用 std::vector<QLabel*>
而不是在创建标签时 push_back
每个标签?可能在成员函数中?
class C
{
std::vector<QLabel*> labels;
public:
void createLabel(char const* text)
{
QLabel* label; // create it as needed, add it to designated parent
labels.push_back(label);
// alternative: create it above without parent
// and return it here (change signature appropriately)
}
};
编辑 回复您的评论:
对于在 QT 设计器中使用,自定义标签可能会帮助您:
class MyLabel : public QLabel
{
static std::vector<MyLabel*> instances;
public:
MyLabel(/* whatever you need */)
: QLabel(/*...*/)
{
instances.push_back(this);
}
~MyLabel()
{
instances.erase
(
std::remove(instances.begin(), instances.end(), this),
instances.end()
);
}
// static begin() and end() functions returning (const_)iterators to your vector
};
QT 设计器也支持(至少在一定程度上)自定义小部件,根据 here。
在 Qt 中,您可以使用 findChildren 函数:
QList<QLabel*> list = this->findChildren<QLabel*>(QRegularExpression("label\d+$"));
这将 return 指向名为 labelX
的 this
的 QLabels 子项的指针的 QList(其中 X
至少是一位数字)。
LE:通过阅读评论,我假设它没有按您想要的方式排序,因此您可以使用 QCollator 对字符串进行数字排序,如下所示:
QCollator c;
c.setNumericMode(true);
std::sort(list.begin(), list.end(), [&c](QLabel* lhs, QLabel* rhs) {
if(c.compare(lhs->objectName(), rhs->objectName()) < 0)
return true;
return false;
});
我有一个 Qt 项目,其中 ui 在 Qt Designer 中创建。 ui 当前包含 16 个 QLabel。我需要一个包含所有 QLabel 的数组。目前我初始化数组:
labels_ = {ui->label0, ui->label1, ui->label2, ui->label3, ui->label4,
ui->label5, ui->label6, ui->label7, ui->label8, ui->label9,
ui->label10, ui->label11, ui->label12, ui->label13, ui->label14,
ui->label15};
我希望以后能够轻松地向 ui 表单添加和删除 QLabel。如果在某个时候我想用 100 个 QLabel 测试程序怎么办?
我发现 Boost.preprocessor 我可以做到这一点:
#define NLABELS 16
#define FILL_ARRAY(z, idx, name) \
BOOST_PP_CAT(name, idx),
labels_ = {BOOST_PP_REPEAT(NLABELS, FILL_ARRAY, ui->label)};
但是,我仍然在犹豫这是否是正确的做法。也许 Qt 有一些其他功能来实现这一点?
对我来说似乎是正确的,Qt 没有这方面的功能。
为什么不使用 std::vector<QLabel*>
而不是在创建标签时 push_back
每个标签?可能在成员函数中?
class C
{
std::vector<QLabel*> labels;
public:
void createLabel(char const* text)
{
QLabel* label; // create it as needed, add it to designated parent
labels.push_back(label);
// alternative: create it above without parent
// and return it here (change signature appropriately)
}
};
编辑 回复您的评论:
对于在 QT 设计器中使用,自定义标签可能会帮助您:
class MyLabel : public QLabel
{
static std::vector<MyLabel*> instances;
public:
MyLabel(/* whatever you need */)
: QLabel(/*...*/)
{
instances.push_back(this);
}
~MyLabel()
{
instances.erase
(
std::remove(instances.begin(), instances.end(), this),
instances.end()
);
}
// static begin() and end() functions returning (const_)iterators to your vector
};
QT 设计器也支持(至少在一定程度上)自定义小部件,根据 here。
在 Qt 中,您可以使用 findChildren 函数:
QList<QLabel*> list = this->findChildren<QLabel*>(QRegularExpression("label\d+$"));
这将 return 指向名为 labelX
的 this
的 QLabels 子项的指针的 QList(其中 X
至少是一位数字)。
LE:通过阅读评论,我假设它没有按您想要的方式排序,因此您可以使用 QCollator 对字符串进行数字排序,如下所示:
QCollator c;
c.setNumericMode(true);
std::sort(list.begin(), list.end(), [&c](QLabel* lhs, QLabel* rhs) {
if(c.compare(lhs->objectName(), rhs->objectName()) < 0)
return true;
return false;
});