当前位置: 首页 > article >正文

记录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);
}


http://www.kler.cn/a/322585.html

相关文章:

  • 使用Python编写一个简单的网页爬虫,从网站抓取标题和内容。
  • Debezium日常分享系列之:Debezium3版本Debezium connector for JDBC
  • 深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解
  • 实用教程:如何无损修改MP4视频时长
  • 【爬虫实战】抓取某站评论
  • Excel根据条件动态索引单元格范围
  • cubemx配置ADC
  • [3]Opengl ES着色器
  • ST188单光束反射式红外光电传感器心率测量原理
  • 混拨动态IP代理的优势是什么
  • 网络编程(10)——json序列化
  • leetcode721. 账户合并
  • 高级算法设计与分析 学习笔记9 跳表
  • 【论文阅读】RISE: 3D Perception Makes Real-World Robot Imitation Simple and Effective
  • 动态规划入门题目->使用最小费用爬楼梯
  • Ceph 基本架构(一)
  • Docker实践与应用
  • QT开发模式(一):界面和业务逻辑分离
  • 基于Hive和Hadoop的电商消费分析系统
  • 人工智能之计算机视觉的发展历程与相关技术内容,相应的模型介绍
  • docker-文件复制(docker cp:用于在Docker主机和容器之间拷贝文件或目录)
  • Windows系统的Tomcat日志路径配置
  • 在 Ubuntu 上构建 Electron 项目时的问题记录和解决方法
  • Meta的LLaMA 3.2系列大模型打败OpenAI,Orion的原型AR眼镜更是引领科技新时代!
  • WiFi无线连接管理安卓设备工具:WiFiADB
  • 初学者教程:如何使用谷歌云API