Qt_ui_headerlabel被覆盖问题总结
.ui 文件中 setupUi() 会重设 header,导致构造函数中 setHeaderLabels() 设置被覆盖。
Qt_ui_headerlabel被覆盖问题总结
Qt_ui_headerlabel被覆盖问题总结
ProTreeWidget 类定义与实现(自定义 QTreeWidget)
protreewidget.h
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef PROTREEWIDGET_H
#define PROTREEWIDGET_H
#include <QTreeWidget>
class ProTreeWidget : public QTreeWidget {
Q_OBJECT
public:
ProTreeWidget(QWidget* parent = nullptr);
};
#endif // PROTREEWIDGET_H
protreewidget.cpp
1
2
3
4
5
6
7
#include "protreewidget.h"
#include <QDebug>
ProTreeWidget::ProTreeWidget(QWidget* parent) : QTreeWidget(parent) {
setHeaderLabels(QStringList() << "项目名称222" << "路径");
qDebug() << "ProTreeWidget 构造函数";
}
ProTreeDialog 类实现
protreedialog.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "protreedialog.h"
#include "ui_protreedialog.h"
#include <QDebug>
ProTreeDialog::ProTreeDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ProTreeDialog) {
ui->setupUi(this); // setupUi 之后 header 会被覆盖
// 正确做法:在这里设置 headerLabels 才不会被 UI 覆盖
ui->treeWidget->setHeaderLabels(QStringList() << "项目名称" << "路径");
qDebug() << "ProTreeDialog 构造函数";
}
ProTreeDialog::~ProTreeDialog() {
delete ui;
}
UI 自动生成代码片段(ui_protreedialog.h)
这是 Qt Designer 生成的 UI 代码中关键的一段:
1
2
3
4
5
6
treeWidget = new ProTreeWidget(ProTreeDialog);
// Qt Designer 默认设置了一列名为“1”
QTreeWidgetItem *__qtreewidgetitem = new QTreeWidgetItem();
__qtreewidgetitem->setText(0, QString::fromUtf8("1"));
treeWidget->setHeaderItem(__qtreewidgetitem); // 这里会覆盖 headerLabels
ProTreeWidget
构造函数中设置的setHeaderLabels(...)
,会在 setupUi() 调用时被覆盖;覆盖行为来自
.ui
文件生成的代码中的setHeaderItem(...)
;正确设置 header 的时机是在
setupUi()
之后,例如在ProTreeDialog
构造函数末尾。
解决方法
方法一
不要在构造函数中 setHeaderLabels,改成在 ProTreeDialog
构造函数末尾设置**
1
2
3
4
ProTreeDialog::ProTreeDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ProTreeDialog) {
ui->setupUi(this); // setupUi 之后才可以覆盖
ui->treeWidget->setHeaderLabels(QStringList() << "项目名称" << "路径"); // 推荐写在这里
}
方法二
修改 .ui
文件中的 TreeWidget
- 打开
protreedialog.ui
。 - 选中
treeWidget
控件。 - 设置列数为 2。
- 设置列名为:项目名称、路径。
- 保存、重新构建,生成的
ui_protreedialog.h
代码就会是:
1
2
3
4
QTreeWidgetItem *__qtreewidgetitem = new QTreeWidgetItem();
__qtreewidgetitem->setText(0, QString::fromUtf8("项目名称"));
__qtreewidgetitem->setText(1, QString::fromUtf8("路径"));
treeWidget->setHeaderItem(__qtreewidgetitem);
为什么 Qt Designer 会生成 setHeaderItem
Qt Designer 并不知道 ProTreeWidget
的构造函数里面写了什么。它会默认给 QTreeWidget
添加一列 "1"
作为 placeholder header,这是 Qt Designer 的默认行为。
本文由作者按照 CC BY 4.0 进行授权