记录QTreeView使用(item勾选,事件,过滤)

QTreeView: 用于显示树状结构数据,适用于树状结构数据的操作。

        在开发过程中很多时候需要用到树形结构的视图。在Qt中通常有QTreewidget以及QTreeView两种选择,对于QTreewidget它已经内置了一个数据模型,并且提供了方便的API来操作和管理树形结构的数据。通常用于数据简单,数据项少,解耦程度要求低的场合。但是代码非常简单。使用QTreeView可以更灵活地处理不同类型的树形结构数据,并进行自定义样式、编辑等操作等。

QTreeView本身不存储数据,而是通过与数据模型(如QStandardItemModel、QFileSystemModel等)的结合来展示数据。你需要先创建一个数据模型,并将其设置给QTreeView。

例子:

关键代码

1.初始化树

void QTreeViewDemo::initTree()
{
	model = new QStandardItemModel(ui.treeView);
	//设置树形结构表头信息
	model->setHorizontalHeaderLabels(QStringList() << QStringLiteral("文件名") << QStringLiteral("数据信息"));

	//设置树形结构根节点信息
	QStandardItem* itemProject = new QStandardItem(QIcon(":/QTreeViewDemo/Resources/folder.png"), QStringLiteral("电脑"));
	//itemProject->setData("根节点", Qt::UserRole + 1);  // 用户数据
	model->appendRow(itemProject);

	model->setItem(model->indexFromItem(itemProject).row(), 1, new QStandardItem(QStringLiteral("信息说明")));
	QStandardItem* itemFolder = new QStandardItem(QIcon(":/QTreeViewDemo/Resources/folder.png"), QStringLiteral("文件夹1"));
	itemProject->appendRow(itemFolder);
	//itemFolder->setData("一级节点", Qt::UserRole + 1);  // 用户数据

	itemProject->setChild(itemFolder->index().row(), 1, new QStandardItem(QStringLiteral("信息说明")));
	itemFolder = new QStandardItem(QIcon(":/QTreeViewDemo/Resources/folder.png"), QStringLiteral("文件夹2"));
	itemProject->appendRow(itemFolder);
	for (int i = 0; i < 5; ++i) {
		QStandardItem* itemgroup = new QStandardItem(QIcon(":/QTreeViewDemo/Resources/folder.png"), QStringLiteral("Group%1").arg(i + 1));
		itemFolder->appendRow(itemgroup);
		for (int j = 0; j < (i + 1); ++j) {
			QStandardItem* itemchannel = new QStandardItem(QIcon(":/QTreeViewDemo/Resources/folder.png"), QStringLiteral("文件%1").arg(j + 1));
			itemgroup->appendRow(itemchannel);
			itemgroup->setChild(itemchannel->index().row(), 1, new QStandardItem(QStringLiteral("文件%1信息说明").arg(j + 1)));
		}
	}
	itemProject->setChild(itemFolder->index().row(), 1, new QStandardItem(QStringLiteral("文件夹2信息说明")));


	itemProject = new QStandardItem(QIcon(":/QTreeViewDemo/Resources/folder.png"), QStringLiteral("手机"));
	itemProject->setCheckable(true);//设置有勾选框
	itemProject->setTristate(true);//

	model->appendRow(itemProject);
	for (int i = 0; i < 3; ++i)
	{
		itemFolder = new QStandardItem(QIcon(":/QTreeViewDemo/Resources/folder.png"), QStringLiteral("文件夹%1").arg(i + 1));
		itemFolder->setCheckable(true);
		itemFolder->setTristate(true);
		QStandardItem* itemFolderDes = new QStandardItem(QIcon(":/QTreeViewDemo/Resources/folder.png"), QStringLiteral("Group%1").arg(i + 1));
		itemProject->appendRow(itemFolder);
		itemProject->setChild(itemFolder->index().row(), 1, itemFolderDes);
		for (int j = 0; j < i + 1; ++j)
		{
			QStandardItem* item = new QStandardItem(QIcon(":/QTreeViewDemo/Resources/folder.png"), QStringLiteral("文件%1").arg(j + 1));
			item->setCheckable(true);
			itemFolder->appendRow(item);

			itemFolder->setChild(item->index().row(), 1, new QStandardItem(QStringLiteral("文件%1信息说明").arg(j + 1)));

		}
	}

	//关联项目属性改变的信号和槽
	connect(model, &QStandardItemModel::itemChanged, this, &QTreeViewDemo::treeItemChanged);

	ui.treeView->setModel(model);
	ui.treeView->setColumnWidth(0,150);
	ui.treeView->expandAll();
	ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu);
	connect(ui.treeView, &QTreeView::customContextMenuRequested, this, &QTreeViewDemo::onTreeViewMenuRequested);
}

2.单击item事件

void QTreeViewDemo::on_treeView_clicked(const QModelIndex &index)
{
	//QStandardItem* item = mModel->itemFromIndex(index);
	ui.textEdit->append("Clicked "+ index.data().toString());



	QString str;
	str += QStringLiteral("当前选中:%1\nrow:%2,column:%3\n").arg(index.data().toString())
		.arg(index.row()).arg(index.column());
	str += QStringLiteral("父级:%1\n").arg(index.parent().data().toString());
	//兄弟节点测试
	QString name, info;
	if (index.column() == 0)
	{
		name = index.data().toString();
		info = index.sibling(index.row(), 1).data().toString();
	}
	else
	{
		name = index.sibling(index.row(), 0).data().toString();
		info = index.data().toString();
	}
	str += QStringLiteral("名称:%1\n信息:%2\n").arg(name).arg(info);
	//寻找顶层
	QString top = getTopParent(index).data().toString();
	str += QStringLiteral("顶层节点名:%1\n").arg(top);


	//当前节点item
	QStandardItem *pItem = model->itemFromIndex(index);
	if (pItem) {
		QString s = pItem->data().toString();

		QVariant variant = pItem->data(Qt::UserRole + 1);  // 获取用户数据
		Test user = variant.value<Test>();

		str += QStringLiteral("当前节点数据信息:%1\n%2\n%3\n").arg(user.text1).arg(user.text2).arg(user.text3);
	}
	//ui->label_realTime->setText(str);
	ui.plainTextEdit->setPlainText(str);


}

3.双击item事件

void QTreeViewDemo::on_treeView_doubleClicked(const QModelIndex & index)
{
	ui.textEdit->append("doubleClicked " + index.data().toString());
}

4.节点添加图标以及勾选框

//添加图标
QStandardItem* itemProject = new QStandardItem(QIcon(":/QTreeViewDemo/Resources/folder.png"), QStringLiteral("电脑"));

//添加勾选框
itemProject->setCheckable(true);

5.节点勾选事件触发

(1)Item全部选中

void QTreeViewDemo::treeItem_checkAllChild(QStandardItem * item, bool check)
{
	if (item == nullptr)
		return;
	int rowCount = item->rowCount();
	for (int i = 0; i < rowCount; ++i)
	{
		QStandardItem* childItems = item->child(i);
		treeItem_checkAllChild_recursion(childItems, check);
	}
	if (item->isCheckable())
		item->setCheckState(check ? Qt::Checked : Qt::Unchecked);
}

(2)item三种状态判断(半选,全选,不选)

void QTreeViewDemo::treeItem_CheckChildChanged(QStandardItem * item)
{
	if (nullptr == item)
		return;
	Qt::CheckState siblingState = checkSibling(item);
	QStandardItem * parentItem = item->parent();
	if (nullptr == parentItem)
		return;
	if (Qt::PartiallyChecked == siblingState)
	{
		if (parentItem->isCheckable() && parentItem->isTristate())
			parentItem->setCheckState(Qt::PartiallyChecked);
	}
	else if (Qt::Checked == siblingState)
	{
		if (parentItem->isCheckable())
			parentItem->setCheckState(Qt::Checked);
	}
	else
	{
		if (parentItem->isCheckable())
			parentItem->setCheckState(Qt::Unchecked);
	}
	treeItem_CheckChildChanged(parentItem);
}

在Python,特别是使用PyQt5库来开发GUI应用时,QTreeView是一个用于显示树形数据结构的控件,而CheckBox(复选框)则可以用来表示每个节点的选状态。如果你想要实现QTreeViewCheckBox的勾选联动效果,通常的做法是在模型(Model)层面上管理这些选状态,并通过信号与槽(Signal and Slot)机制来同步视图(View)。 例如,你可以创建一个自定义的数据模型,如`QStandardItemModel`,并在其关联每个节点和CheckBox的状态。当用户点击某个节点的CheckBox时,模型会更新对应项的选状态,然后通过`emit(SIGNAL("dataChanged(QModelIndex,QModelIndex)"))`发送信号通知视图刷新。 在视图,你需要设置`QTreeView`的模式为单击选择(`setSelectionMode(QAbstractItemView::SingleSelection)`), 并连接模型的`dataChanged`信号到适当的槽函数,在该槽函数处理选状态的变化并更新对应的UI元素。 以下是简单的步骤概述: 1. 创建模型并绑定CheckBox状态到模型item: ```python model = QStandardItemModel() checkbox_item = QStandardItem() checkbox_item.setCheckable(True) # 设置勾选状态 checkbox_item.setCheckState(Qt.Checked) model.setItem(0, 0, checkbox_item) ``` 2. 更新模型时,触发视图的刷新: ```python def update_checkbox_state(index): # 在这里更改模型的数据 model.setData(index, Qt.Checked) self.view.dataChanged.emit(index, index) checkbox_item.stateChanged.connect(update_checkbox_state) ``` 3. 设置QTreeView监听数据变化: ```python view = QTreeView() view.setModel(model) view.selectionModel().selectionChanged.connect(lambda selection: update_checkbox_state(selection.indexes()[0])) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫毅忆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值