目录
一、QTreeWidget 概述
二、QTreeWidget 的基本使用
2.1、创建 QTreeWidget 控件
2.2、设置 QTreeWidget 的大小和位置
2.3、设置 QTreeWidget 的列数和列标题
2.4、添加节点
2.5、读取节点
2.6、设置节点数据
2.7、自定义节点样式
三、注意事项
四、完整示例
QTreeWidget是Qt中一个用于显示树形结构数据的控件,它继承自QTreeView,可以显示多列数据和树形结构的层次关系,还提供了许多交互功能。可以支持单选、多选和可编辑的节点,还可以自定义节点的样式和布局。除此之外,QTreeWidget 还支持信号和槽机制,可以方便地处理节点的操作事件,如点击、双击、选择等等。
头文件: #include
qmake: QT += widgets
继承: QTreeView
使用 QTreeWidget 控件前,首先需要在代码中创建 QTreeWidget 实例。代码如下:
QTreeWidget *tree = new QTreeWidget();
这里创建了一个 QTreeWidget 实例,并将其保存在 tree 指针中。此时,tree 控件还没有设置显示大小和位置,需要设置它们才能正常显示。
在 Qt 中,可以使用 QWidget::resize() 和 QWidget::move() 函数来设置控件的大小和位置。代码如下:
tree->resize(400, 300); // 设置控件大小为 400 x 300
tree->move(100, 100); // 设置控件在窗口中的位置为 (100, 100)
这里设置了 tree 控件的大小为 400 x 300 像素,并将其移动到窗口的 (100, 100) 像素处。
QTreeWidget 可以显示多列数据,可以使用 QTreeWidget::setColumnCount() 和 QTreeWidget::setHeaderLabels() 函数来设置列数和列标题。代码如下:
tree->setColumnCount(2); // 设置列数为 2
tree->setHeaderLabels({"Name", "Value"}); // 设置列标题为 "Name" 和 "Value"
这里设置了 tree 控件的列数为 2,列标题分别为 "Name" 和 "Value"。
QTreeWidget 中的每个节点都是一个 QTreeWidgetItem 实例,可以使用 QTreeWidget::addTopLevelItem()、QTreeWidgetItem::addChild() 和 QTreeWidget::insertTopLevelItem() 函数来添加节点。代码如下:
QTreeWidgetItem *root = new QTreeWidgetItem(tree); // 创建一个根节点
root->setText(0, "Root"); // 设置节点文本
root->setText(1, "0"); // 设置节点文本
tree->addTopLevelItem(root); // 将节点添加到 QTreeWidget 中
QTreeWidgetItem *child1 = new QTreeWidgetItem(root); // 创建一个子节点
child1->setText(0, "Child 1"); // 设置节点文本
child1->setText(1,"10"); // 设置节点文本
root->addChild(child1); // 将节点添加到根节点下
QTreeWidgetItem *child2 = new QTreeWidgetItem(root); // 创建另一个子节点
child2->setText(0, "Child 2"); // 设置节点文本
child2->setText(1, "20"); // 设置节点文本
tree->insertTopLevelItem(0, child2); // 将节点插入到 QTreeWidget 的第一个位置
这里创建了一个根节点 root,其文本为 "Root" 和 "0",并将其添加到 QTreeWidget 中。然后创建了两个子节点 child1 和 child2,分别作为 root 的子节点,并设置其文本。注意,要将子节点添加到父节点中,可以使用 QTreeWidgetItem::addChild() 函数或 QTreeWidget::insertTopLevelItem() 函数。
可以使用 QTreeWidget::topLevelItem() 和 QTreeWidgetItem::child() 函数来读取节点。代码如下:
QTreeWidgetItem *item = tree->topLevelItem(0); // 获取第一个根节点
if (item) {
QString text1 = item->text(0); // 获取节点的第一列文本
QString text2 = item->text(1); // 获取节点的第二列文本
qDebug() << text1 << text2; // 输出节点文本
QTreeWidgetItem *child = item->child(0); // 获取根节点的第一个子节点
if (child) {
QString text3 = child->text(0); // 获取子节点的第一列文本
QString text4 = child->text(1); // 获取子节点的第二列文本
qDebug() << text3 << text4; // 输出子节点文本
}
}
这里先获取了 QTreeWidget 的第一个根节点,并输出其文本。然后获取根节点的第一个子节点,并输出其文本。
QTreeWidgetItem 可以存储自定义数据,可以使用 QTreeWidgetItem::setData() 函数来设置节点的数据。代码如下:
QTreeWidgetItem *item = tree->topLevelItem(0); // 获取第一个根节点
if (item) {
item->setData(2, Qt::UserRole, "custom data"); // 设置第三列的自定义数据
}
// 读取节点数据可以使用item->data(2, Qt::UserRole).toString();
这里设置了根节点的第三列数据为 "custom data"。
QTreeWidget 的节点可以根据需求进行自定义样式的设置。可以使用 QTreeWidget::setItemDelegate() 函数来设置 QItemDelegate,从而实现节点样式的自定义。代码如下:
class MyDelegate : public QItemDelegate
{
public:
MyDelegate(QObject *parent = nullptr) : QItemDelegate(parent) {}
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override {
QStyleOptionViewItem opt = option;
if (opt.state & QStyle::State_Selected) {
painter->fillRect(opt.rect, opt.palette.highlight());
opt.palette.setColor(QPalette::Text, opt.palette.highlightedText().color());
}
painter->drawText(opt.rect, Qt::AlignVCenter | Qt::AlignLeft | Qt::TextWordWrap, index.data(Qt::DisplayRole).toString());
}
};
// 在创建 QTreeWidget 对象后设置自定义的 QItemDelegate
QTreeWidget *tree = new QTreeWidget(parent);
tree->setItemDelegate(new MyDelegate(tree));
这里定义了一个 MyDelegate 类来继承自 QItemDelegate,重写了其 paint() 函数以实现节点样式的自定义。在创建 QTreeWidget 对象后,使用 QTreeWidget::setItemDelegate() 函数设置自定义的 QItemDelegate。
1、 QTreeWidget 中的数据存储在 QTreeWidgetItem 中,因此在对 QTreeWidget 进行数据操作时,必须同时对其对应的 QTreeWidgetItem 进行相应的操作。
2、 QTreeWidget 的节点数据的列数默认为 1,可以使用 QTreeWidget::setColumnCount() 函数进行设置。
3、 QTreeWidgetItem 的列数必须与 QTreeWidget 的列数相同,否则节点的数据将无法正确显示。
#include
#include
#include
#include
#include
#include
#include
class MyDelegate : public QItemDelegate
{
public:
MyDelegate(QObject *parent = nullptr) : QItemDelegate(parent) {}
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override {
QStyleOptionViewItem opt = option;
if (opt.state & QStyle::State_Selected) {
painter->fillRect(opt.rect, opt.palette.highlight());
opt.palette.setColor(QPalette::Text, opt.palette.highlightedText().color());
}
painter->drawText(opt.rect, Qt::AlignVCenter | Qt::AlignLeft
| Qt::TextWordWrap, index.data(Qt::DisplayRole).toString());
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// 创建 QTreeWidget 对象
QTreeWidget *tree = new QTreeWidget;
tree->setColumnCount(3); // 设置列数为 3
tree->setHeaderLabels({"Name", "Value", "Data"}); // 设置列标签
tree->header()->setSectionResizeMode(QHeaderView::ResizeToContents); // 自适应列宽
// 创建根节点
QTreeWidgetItem *root = new QTreeWidgetItem(tree);
root->setText(0, "Root");
root->setText(1, "0");
root->setData(2, Qt::UserRole, "root data");
tree->addTopLevelItem(root);
// 创建子节点 1
QTreeWidgetItem *child1 = new QTreeWidgetItem(root);
child1->setText(0, "Child 1");
child1->setText(1, "10");
root->addChild(child1);
// 创建子节点 2
QTreeWidgetItem *child2 = new QTreeWidgetItem(root);
child2->setText(0, "Child 2");
child2->setText(1, "20");
tree->insertTopLevelItem(0, child2);
// 设置自定义样式
tree->setItemDelegate(new MyDelegate(tree));
// 读取节点数据
QTreeWidgetItem *item = tree->topLevelItem(0);
if (item) {
qDebug() << "Root name: " << item->text(0); // 输出 "Root"
qDebug() << "Root value: " << item->text(1); // 输出 "0"
qDebug() << "Root data: " << item->data(2, Qt::UserRole).toString(); // 输出 "root data"
}
// 显示 QTreeWidget 对象
tree->show();
return app.exec();
}
运行上述示例程序,可以看到一个简单的 QTreeWidget 对象,其中包含三列数据,根节点下有两个子节点。