QT笔记——QTableWidget表格生成树,QTreeWidget树节点生成表格内容

目的:我们通过表格中的数据生成一个树,然后通过点击树的分支可以得到该树上节点所保存的数据显示在另外一个表格上。

一个生成树的表格以及数据
QT笔记——QTableWidget表格生成树,QTreeWidget树节点生成表格内容_第1张图片
生成树的内容为:
QT笔记——QTableWidget表格生成树,QTreeWidget树节点生成表格内容_第2张图片
通过点击树的节点,显示该树节点显示的内容:
QT笔记——QTableWidget表格生成树,QTreeWidget树节点生成表格内容_第3张图片
1.我们需要根据表格的内容生成树
1.1某列中寻找目标字符串

QList<QTableWidgetItem*> qtreewidgetTest::findItem(const QString& target, int column)
{
	//存放寻找到该列的字符串
	QList<QTableWidgetItem *> list;
	QString str;
	int row = ui.tableWidget2->rowCount();
	int col = ui.tableWidget2->columnCount();
	//遍历列表 寻找目标字符串
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col;j++)
		{
			//如果不是该列
			if(j != column)
				continue;
			//该列的字符串与目标字符进行比较
			str = ui.tableWidget2->item(i, j)->text();
			if (target == str)
			{
				list.push_back(ui.tableWidget2->item(i, j));
			}
		}
	}

	return  list;
}

1.2递归该父亲节点的所有孩子

void qtreewidgetTest::departTree(int fatherRow, QTreeWidgetItem* item)
{
	//传进来的是他的父亲节点
	//通过父亲节点再去找他的子节点
	QList <QTableWidgetItem*> list;
	//父亲节点的ID号
	QString id = ui.tableWidget2->item(fatherRow, colItem)->text();
	//找到所有该父亲节点下的孩子
	list = findItem(id, colItem2);

	int sonRow;
	QString name;
	if (!list.isEmpty())
	{
		for (int i = 0 ; i < list.size(); i++)
		{
			//该孩子的行数并且获取该孩子的名称
			sonRow = list.at(i)->row();
			name = ui.tableWidget2->item(sonRow, colItem1)->text();
			QTreeWidgetItem* newItem = new QTreeWidgetItem(item, QStringList(name));
			//添加到传进来的父节点身上
			item->addChild(item);
			//递归该父节点每个孩子身上有没有子孩子
			departTree(sonRow, newItem);
		}
	}
}

1.3生成树

void qtreewidgetTest::initTree()
{
	QList<QTableWidgetItem*> list;
	//如果父节点为1  说明此节点为根节点
	QString str = "1";
	list = findItem(str, colItem2);
	int row;
	QString name;
	//根节点
	if (!list.isEmpty()) 
	{
		for (int i = 0; i < list.size(); ++i) 
		{
			row = list.at(i)->row();
			name = ui.tableWidget2->item(row, colItem1)->text();
			QTreeWidgetItem* item = new QTreeWidgetItem(ui.treeWidget, QStringList(name));
			//设置顶级节点(即根节点)
			ui.treeWidget->addTopLevelItem(item);
			//递归该父亲节点的所有孩子节点
			departTree(row, item);
		}
	}
	ui.treeWidget->expandAll();

}

2.我们需要给树节点内容,然后通过点击树节点将内容显示在表格中

	//遍历树列表
	QTreeWidgetItemIterator it(ui.treeWidget);
	while (*it) 
	{
		if ((*it)->text(0) == QStringLiteral("销售1部"))
		{
			QVariant varData;
			varData.setValue(createMap(*it, list));
			(*it)->setData(0, Qt::UserRole, QVariant::fromValue(varData));
		}		
		else if ((*it)->text(0) == QStringLiteral("人事部"))
		{
			QVariant varData1;
			varData1.setValue(createMap(*it, list1));
			(*it)->setData(0, Qt::UserRole, QVariant::fromValue(varData1));
		}

		//(*it)->text(0);
		++it;
	}

点击树节点:

//定义SLOTS
public slots:
	void si_itemClicked(QTreeWidgetItem* item, int column);
//连接点击树节点信号
	connect(ui.treeWidget, SIGNAL(itemClicked(QTreeWidgetItem* ,int)), this, SLOT(si_itemClicked(QTreeWidgetItem*, int)));
//在SLOT中将数据添加到表格中

完整代码:

#pragma once

#include 
#include "ui_qtreewidgetTest.h"
#include 
#include 
#include 
#include 
#include 
struct Person
{
	QString name;
	int age;
	int score;
	QString className;
};
Q_DECLARE_METATYPE(Person)
class qtreewidgetTest : public QWidget
{
	Q_OBJECT
	enum tableColumn
	{
		colItem = 0,
		colItem1 ,
		colItem2,
	};
public:
	qtreewidgetTest(QWidget *parent = Q_NULLPTR);
	~qtreewidgetTest();
	QMap <QString, QList<Person>> createMap(QTreeWidgetItem* item, QList<Person> & list);	//当前树的节点的名称 个数 数据
	void init_TableWidget2();																//初始化列表
	QList<QTableWidgetItem*> findItem(const QString& target, int column);					//找到当前目标的子item
	void departTree(int row, QTreeWidgetItem* item);										//更新树
	void initTree();


public slots:
	void si_itemClicked(QTreeWidgetItem* item, int column);
private:
	Ui::qtreewidgetTestClass ui;

};
#include "qtreewidgetTest.h"

qtreewidgetTest::qtreewidgetTest(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	init_TableWidget2();
	ui.treeWidget->setHeaderHidden(true);
	initTree();
	
	//设置数据源
	Person p = { QStringLiteral("小宋"),20,60,QStringLiteral("2班") };
	Person p1 = { QStringLiteral("王五"),26,90,QStringLiteral("2班") };
	Person p2 = { QStringLiteral("小明"),24,70,QStringLiteral("1班") };
	Person p3 = { QStringLiteral("小李"),30,50,QStringLiteral("4班") };

	//插入数据
	QList<Person> list;
	list.append(p);
	list.append(p1);
	list.append(p2);
	list.append(p3);


	Person p5 = { QStringLiteral("小胡"),20,60,QStringLiteral("3班") };
	Person p6 = { QStringLiteral("小陈"),26,90,QStringLiteral("2班") };
	Person p4 = { QStringLiteral("小哦"),24,70,QStringLiteral("6班") };
	QList<Person> list1;
	list1.append(p4);
	list1.append(p5);
	list1.append(p6);

	//遍历树列表
	QTreeWidgetItemIterator it(ui.treeWidget);
	while (*it) 
	{
		if ((*it)->text(0) == QStringLiteral("销售1部"))
		{
			QVariant varData;
			varData.setValue(createMap(*it, list));
			(*it)->setData(0, Qt::UserRole, QVariant::fromValue(varData));
		}		
		else if ((*it)->text(0) == QStringLiteral("人事部"))
		{
			QVariant varData1;
			varData1.setValue(createMap(*it, list1));
			(*it)->setData(0, Qt::UserRole, QVariant::fromValue(varData1));
		}

		//(*it)->text(0);
		++it;
	}


	//设置表格属性
	ui.tableWidget1->setColumnCount(4);
	ui.tableWidget1->verticalHeader()->hide();
	ui.tableWidget1->setEditTriggers(QAbstractItemView::NoEditTriggers);
	ui.tableWidget1->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

	//设置表头
	QStringList head;
	head << QStringLiteral("姓名") << QStringLiteral("年龄") << QStringLiteral("分数") << QStringLiteral("班级");
	ui.tableWidget1->setHorizontalHeaderLabels(head);

	connect(ui.treeWidget, SIGNAL(itemClicked(QTreeWidgetItem* ,int)), this, SLOT(si_itemClicked(QTreeWidgetItem*, int)));
}

qtreewidgetTest::~qtreewidgetTest()
{

}


QMap<QString, QList<Person>> qtreewidgetTest::createMap(QTreeWidgetItem * item, QList<Person>& p)
{
	QMap <QString, QList<Person>> list;
	list.insert(item->text(0), p);

	return list;

}

void qtreewidgetTest::init_TableWidget2()
{
	ui.tableWidget2->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);	//水平表格自适应
	ui.tableWidget2->setEditTriggers(QAbstractItemView::NoEditTriggers);

	QStringList tab2List;
	tab2List << "ID" << QStringLiteral("名称") << "parent_ID";
	ui.tableWidget2->setHorizontalHeaderLabels(tab2List);
}

QList<QTableWidgetItem*> qtreewidgetTest::findItem(const QString& target, int column)
{
	//存放寻找到该列的字符串
	QList<QTableWidgetItem *> list;
	QString str;
	int row = ui.tableWidget2->rowCount();
	int col = ui.tableWidget2->columnCount();
	//遍历列表 寻找目标字符串
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col;j++)
		{
			//如果不是该列
			if(j != column)
				continue;
			//该列的字符串与目标字符进行比较
			str = ui.tableWidget2->item(i, j)->text();
			if (target == str)
			{
				list.push_back(ui.tableWidget2->item(i, j));
			}
		}
	}

	return  list;
}

void qtreewidgetTest::departTree(int fatherRow, QTreeWidgetItem* item)
{
	//传进来的是他的父亲节点
	//通过父亲节点再去找他的子节点
	QList <QTableWidgetItem*> list;
	//父亲节点的ID号
	QString id = ui.tableWidget2->item(fatherRow, colItem)->text();
	//找到所有该父亲节点下的孩子
	list = findItem(id, colItem2);

	int sonRow;
	QString name;
	if (!list.isEmpty())
	{
		for (int i = 0 ; i < list.size(); i++)
		{
			//该孩子的行数 获取该孩子的名称
			sonRow = list.at(i)->row();
			name = ui.tableWidget2->item(sonRow, colItem1)->text();
			QTreeWidgetItem* newItem = new QTreeWidgetItem(item, QStringList(name));
			item->addChild(item);
			departTree(sonRow, newItem);
		}
	}
}

void qtreewidgetTest::initTree()
{
	QList<QTableWidgetItem*> list;
	//如果父节点为1  说明此节点为根节点
	QString str = "1";
	list = findItem(str, colItem2);
	int row;
	QString name;
	//根节点
	if (!list.isEmpty()) 
	{
		for (int i = 0; i < list.size(); ++i) 
		{
			row = list.at(i)->row();
			name = ui.tableWidget2->item(row, colItem1)->text();
			QTreeWidgetItem* item = new QTreeWidgetItem(ui.treeWidget, QStringList(name));
			//设置定级节点
			ui.treeWidget->addTopLevelItem(item);
			departTree(row, item);
		}
	}
	ui.treeWidget->expandAll();
}

void qtreewidgetTest::si_itemClicked(QTreeWidgetItem* item, int column)
{
	//清空列表
	ui.tableWidget1->clearContents();
	int rowNum = ui.tableWidget1->rowCount();
	qDebug() << rowNum;
	//移除行数
	for (int i = rowNum - 1; i >= 0; i--)
	{
		ui.tableWidget1->removeRow(i);
	}
	if (item == NULL)
		return;
	QMap <QString, QList<Person>> list = item->data(0, Qt::UserRole).value<QMap <QString, QList<Person>> >();
	for (auto iter = list.begin(); iter != list.end(); ++iter)
	{
		const QList<Person>& plist = iter.value();
		const QString &text = iter.key();
		int row = plist.size();
		//插入行数
		ui.tableWidget1->setRowCount(row);
		//插入表格数据
		for (int i = 0; i < row; i++)
		{
			ui.tableWidget1->setItem(i, 0, new QTableWidgetItem(plist.at(i).name));
			ui.tableWidget1->setItem(i, 1, new QTableWidgetItem(QString::number(plist.at(i).age)));
			ui.tableWidget1->setItem(i, 2, new QTableWidgetItem(QString::number(plist.at(i).score)));
			ui.tableWidget1->setItem(i, 3, new QTableWidgetItem(plist.at(i).className));
		}
	}
	qDebug() << item->text(0);
}

ui图:
QT笔记——QTableWidget表格生成树,QTreeWidget树节点生成表格内容_第4张图片
效果图:
QT笔记——QTableWidget表格生成树,QTreeWidget树节点生成表格内容_第5张图片

参考连接:
https://blog.csdn.net/weixin_45465612/article/details/104530127
https://ask.csdn.net/questions/1063721

你可能感兴趣的:(QT,qt)