一、QTreeWidget概述
QTreeWidget
是Qt框架中用于显示树形结构数据的核心控件,它继承自QTreeView
,提供了基于项的接口,比QTreeView
更易用但灵活性稍低。它能够以层次结构展示数据,是构建复杂UI界面的重要组件。
二、典型应用场景
1. 文件系统浏览器
// 创建文件系统树
QTreeWidget *fileTree = new QTreeWidget;
fileTree->setHeaderLabels({"名称", "大小", "修改日期"});
QTreeWidgetItem *root = new QTreeWidgetItem(fileTree);
root->setText(0, "C:/");
root->setIcon(0, QIcon(":/icons/drive.png"));
// 添加文件夹
QTreeWidgetItem *documents = new QTreeWidgetItem(root);
documents->setText(0, "Documents");
documents->setIcon(0, QIcon(":/icons/folder.png"));
// 添加文件
QTreeWidgetItem *file = new QTreeWidgetItem(documents);
file->setText(0, "report.pdf");
file->setText(1, "2.4 MB");
file->setIcon(0, QIcon(":/icons/pdf.png"));
2. 配置设置界面
// 创建配置树
QTreeWidget *settingsTree = new QTreeWidget;
settingsTree->setHeaderHidden(true);
QTreeWidgetItem *appearance = new QTreeWidgetItem(settingsTree);
appearance->setText(0, "外观设置");
QTreeWidgetItem *theme = new QTreeWidgetItem(appearance);
theme->setText(0, "主题");
theme->setCheckState(0, Qt::Checked);
QTreeWidgetItem *font = new QTreeWidgetItem(appearance);
font->setText(0, "字体大小");
3. 数据分类展示
// 产品分类树
QTreeWidget *categoryTree = new QTreeWidget;
categoryTree->setColumnCount(2);
categoryTree->setHeaderLabels({"分类", "产品数量"});
QTreeWidgetItem *electronics = new QTreeWidgetItem(categoryTree);
electronics->setText(0, "电子产品");
electronics->setText(1, "128");
QTreeWidgetItem *phones = new QTreeWidgetItem(electronics);
phones->setText(0, "手机");
phones->setText(1, "42");
QTreeWidgetItem *laptops = new QTreeWidgetItem(electronics);
laptops->setText(0, "笔记本电脑");
laptops->setText(1, "35");
4. 项目组织结构图
// 公司组织结构树
QTreeWidget *orgTree = new QTreeWidget;
orgTree->setHeaderLabels({"部门", "负责人", "人数"});
QTreeWidgetItem *ceo = new QTreeWidgetItem(orgTree);
ceo->setText(0, "CEO办公室");
ceo->setText(1, "张明");
ceo->setText(2, "5");
QTreeWidgetItem *rd = new QTreeWidgetItem(ceo);
rd->setText(0, "研发部");
rd->setText(1, "李华");
rd->setText(2, "32");
QTreeWidgetItem *sales = new QTreeWidgetItem(ceo);
sales->setText(0, "销售部");
sales->setText(1, "王芳");
sales->setText(2, "28");
三、核心功能与用法
1. 基本操作
// 创建树控件
QTreeWidget *tree = new QTreeWidget(parent);
tree->setColumnCount(3); // 设置列数
tree->setHeaderLabels({"列1", "列2", "列3"}); // 设置标题
// 添加顶级项
QTreeWidgetItem *topItem = new QTreeWidgetItem(tree);
topItem->setText(0, "顶级项");
// 添加子项
QTreeWidgetItem *childItem = new QTreeWidgetItem(topItem);
childItem->setText(0, "子项");
childItem->setCheckState(0, Qt::Unchecked); // 添加复选框
// 设置图标
topItem->setIcon(0, QIcon(":/icons/folder.png"));
// 展开所有项
tree->expandAll();
// 折叠所有项
tree->collapseAll();
2. 数据操作
// 获取选中项
QList<QTreeWidgetItem*> selectedItems = tree->selectedItems();
// 遍历所有项
QTreeWidgetItemIterator it(tree);
while (*it) {
qDebug() << (*it)->text(0);
++it;
}
// 查找特定项
QList<QTreeWidgetItem*> foundItems = tree->findItems("搜索文本", Qt::MatchExactly | Qt::MatchRecursive, 0);
// 删除项
if (selectedItems.count() > 0) {
delete selectedItems.first();
}
3. 信号处理
// 项选择变化
connect(tree, &QTreeWidget::itemSelectionChanged, [=](){
qDebug() << "选择发生变化";
});
// 项展开/折叠
connect(tree, &QTreeWidget::itemExpanded, [=](QTreeWidgetItem *item){
qDebug() << "展开:" << item->text(0);
});
// 项双击
connect(tree, &QTreeWidget::itemDoubleClicked, [=](QTreeWidgetItem *item, int column){
qDebug() << "双击:" << item->text(column);
});
// 项改变(如复选框状态)
connect(tree, &QTreeWidget::itemChanged, [=](QTreeWidgetItem *item, int column){
if (column == 0 && item->checkState(0) == Qt::Checked) {
qDebug() << "选中:" << item->text(0);
}
});
4. 样式定制
/* 基本树控件样式 */
QTreeWidget {
background-color: #FFFFFF;
border: 1px solid #E0E0E0;
font-size: 12px;
}
/* 表头样式 */
QHeaderView::section {
background-color: #F5F7FA;
padding: 6px;
border: none;
border-bottom: 1px solid #E4E7ED;
}
/* 项样式 */
QTreeWidget::item {
height: 28px;
border-bottom: 1px solid #F0F0F0;
}
/* 选中项样式 */
QTreeWidget::item:selected {
background-color: #FFF7F0;
color: #1D2129;
}
/* 分支指示器(三角图标)样式 */
QTreeWidget::branch {
background-color: transparent;
width: 16px;
height: 16px;
}
QTreeWidget::branch:closed::indicator {
image: url(:/icons/triangle-right.svg);
}
QTreeWidget::branch:open::indicator {
image: url(:/icons/triangle-down.svg);
}
四、高级功能实现
1. 自定义委托
class ProgressBarDelegate : public QStyledItemDelegate {
public:
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override {
if (index.column() == 2) { // 第三列显示进度条
int progress = index.data().toInt();
QStyleOptionProgressBar progressBarOption;
progressBarOption.rect = option.rect;
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
progressBarOption.progress = progress;
progressBarOption.text = QString::number(progress) + "%";
progressBarOption.textVisible = true;
QApplication::style()->drawControl(
QStyle::CE_ProgressBar, &progressBarOption, painter);
} else {
QStyledItemDelegate::paint(painter, option, index);
}
}
};
// 使用委托
tree->setItemDelegateForColumn(2, new ProgressBarDelegate);
2. 拖放功能
// 启用拖放
tree->setDragEnabled(true);
tree->setAcceptDrops(true);
tree->setDragDropMode(QAbstractItemView::InternalMove);
// 实现拖放事件
void MyTreeWidget::dropEvent(QDropEvent *event) {
QTreeWidgetItem *target = itemAt(event->pos());
if (!target) return;
QTreeWidgetItem *dragged = currentItem();
if (dragged && dragged != target) {
// 创建副本
QTreeWidgetItem *newItem = dragged->clone();
// 添加到目标
target->addChild(newItem);
// 删除原始项
delete dragged;
}
}
3. 上下文菜单
tree->setContextMenuPolicy(Qt::CustomContextMenu);
connect(tree, &QTreeWidget::customContextMenuRequested,
this, &MyWidget::showContextMenu);
void MyWidget::showContextMenu(const QPoint &pos) {
QTreeWidgetItem *item = tree->itemAt(pos);
if (!item) return;
QMenu menu;
QAction *renameAction = menu.addAction("重命名");
QAction *deleteAction = menu.addAction("删除");
QAction *selected = menu.exec(tree->viewport()->mapToGlobal(pos));
if (selected == renameAction) {
tree->editItem(item);
} else if (selected == deleteAction) {
delete item;
}
}
五、性能优化技巧
-
批量操作优化
tree->setUpdatesEnabled(false); // 开始批量操作 for (int i = 0; i < 1000; ++i) { QTreeWidgetItem *item = new QTreeWidgetItem(tree); item->setText(0, QString("Item %1").arg(i)); } tree->setUpdatesEnabled(true); // 结束批量操作
-
延迟加载
connect(tree, &QTreeWidget::itemExpanded, [=](QTreeWidgetItem *item) { if (item->childCount() == 0) { // 首次展开时加载 loadChildren(item); } });
-
使用模型/视图架构处理大数据
当数据量超过1000项时,考虑使用QTreeView
+QAbstractItemModel
-
合理设置列宽
tree->header()->setSectionResizeMode(0, QHeaderView::Stretch); // 第一列自适应 tree->header()->setSectionResizeMode(1, QHeaderView::Fixed); // 第二列固定宽度 tree->header()->resizeSection(1, 100);
六、最佳实践总结
-
层次结构设计原则
- 保持树结构不超过4层深度
- 每层节点数不超过100个
- 使用清晰的图标区分不同类型
-
用户体验优化
- 提供搜索过滤功能
- 添加右键上下文菜单
- 实现拖放排序
- 支持复选框多选
-
性能与稳定性
- 大数据集使用懒加载
- 避免在主线程进行复杂操作
- 使用信号阻塞防止递归事件
- 及时释放不再使用的项
-
样式与主题
- 使用样式表统一外观
- 适配不同平台风格
- 提供高对比度模式支持
- 确保选中状态清晰可见