首先创建.xml文件,类型如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Group GroupID="1" MainIndex="0" Name="湖南">
<Back GroupID="1" indexID="1" strName="changde" Describe="常德"/>
<Back GroupID="1" indexID="2" strName="changsha" Describe="长沙"/>
<Back GroupID="1" indexID="3" strName="yongzhou" Describe="永州"/>
<Back GroupID="1" indexID="4" strName="hengyang" Describe="衡阳"/>
<Back GroupID="1" indexID="5" strName="chenzhou" Describe="郴州"/>
<Back GroupID="1" indexID="6" strName="yueyang" Describe="岳阳"/>
<Back GroupID="1" indexID="7" strName="zhangjiajie" Describe="张家界"/>
<Back GroupID="1" indexID="8" strName="yiyang" Describe="益阳"/>
</Group>
<Group GroupID="2" MainIndex="0" Name="广东">
<Back GroupID="2" indexID="1" strName="guangzhou" Describe="广州"/>
<Back GroupID="2" indexID="2" strName="shenzhen" Describe="深圳"/>
<Back GroupID="2" indexID="3" strName="qingyuan" Describe="清远"/>
<Back GroupID="2" indexID="4" strName="zhaoqing" Describe="肇庆"/>
<Back GroupID="2" indexID="5" strName="zhanjiang" Describe="湛江"/>
<Back GroupID="2" indexID="6" strName="jiangmen" Describe="江门"/>
<Back GroupID="2" indexID="7" strName="zhongshan" Describe="中山"/>
<Back GroupID="2" indexID="8" strName="huizhou" Describe="惠州"/>
</Group>
</Root>
上代码头文件
/*************************************************************************
File name: loadxmlTEST.h
Author: ZHOU
Version: V1.0.0
Finished Date: 2022-05-26
Modified Date: 2022-05-26
Description: 测试读取xml,用树状图显示
**************************************************************************/
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_loadxmlTEST.h"
#include <QXmlStreamReader>
#include <QCoreApplication>
#include <QTreeWidgetItem>
struct cityinfo
{
QString Name;
QString Spell;
};
struct CityData
{
QString strName;
QList<cityinfo> cityinfolist;
};
class loadxmlTEST : public QMainWindow
{
Q_OBJECT
public:
loadxmlTEST(QWidget *parent = Q_NULLPTR);
private:
void loadxml(QString tmpPath);
QList<cityinfo> loadDataXml(QXmlStreamReader *reader);
void initselectwidget();//初始化选择窗口
void updateTreewidget(QTreeWidgetItem *item);//更新树状图
void getTreewidgetData();//获取选中状态
private slots:
void slotextarct();
void slotopenfile();
void slotTreewidgetChange(QTreeWidgetItem* item, int column);
private:
Ui::loadxmlTESTClass ui;
};
上代码cpp:
#include "loadxmlTEST.h"
#include <QObject>
#include <QFileDialog>
#pragma execution_character_set("utf-8")
QList<CityData> myCityDatalist;
loadxmlTEST::loadxmlTEST(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
connect(ui.btnextarct, SIGNAL(clicked()), this, SLOT(slotextarct()));
connect(ui.actionopen, SIGNAL(triggered()), this, SLOT(slotopenfile()));
myCityDatalist.clear();
}
void loadxmlTEST::slotextarct()
{
getTreewidgetData();
}
void loadxmlTEST::loadxml(QString tmpPath)
{
QFile file(tmpPath);
myCityDatalist.clear();
if (!file.open(QIODevice::ReadOnly|QIODevice::Text))
{
return;
}
ui.textBrowser->clear();
QXmlStreamReader reader(&file);
while (!reader.atEnd())//单行读取
{
reader.readNext();
QString Elename = reader.name().toString();
CityData myCityData;
if (reader.isStartElement() && Elename=="Group")//读取组别信息
{
QXmlStreamAttributes attribute = reader.attributes();
if (attribute.hasAttribute("Name"))
{
//获得组别名称
myCityData.strName = attribute.value("Name").toString();
}
myCityData.cityinfolist=loadDataXml(&reader);
myCityDatalist.append(myCityData);
}
}
}
QList<cityinfo> loadxmlTEST::loadDataXml(QXmlStreamReader *reader)
{
QList<cityinfo> mycityinfolist;
if (reader==nullptr)
{
return mycityinfolist;
}
while (!reader->atEnd())
{
cityinfo mycityinfo;
reader->readNext();
QString Elename = reader->name().toString();
if (reader->isStartElement() && Elename==tr("Back"))
{
QXmlStreamAttributes attribute = reader->attributes();
if (attribute.hasAttribute("strName"))
{
mycityinfo.Name = attribute.value("strName").toString();
}
if (attribute.hasAttribute("Describe"))
{
mycityinfo.Spell = attribute.value("Describe").toString();
}
mycityinfolist.append(mycityinfo);
}
if (reader->isEndElement() && Elename=="Group")//结束
{
break;
}
}
return mycityinfolist;
}
void loadxmlTEST::initselectwidget()
{
ui.treeWidget->clear();
for (auto dataitem:myCityDatalist)
{
QTreeWidgetItem *topitem = new QTreeWidgetItem;
topitem->setText(0, dataitem.strName);
topitem->setCheckState(0, Qt::Unchecked);
ui.treeWidget->addTopLevelItem(topitem);
for (auto cityitem : dataitem.cityinfolist)
{
QTreeWidgetItem *item = new QTreeWidgetItem(topitem);
item->setText(0, cityitem.Spell);
item->setText(1, cityitem.Name);
item->setCheckState(0, Qt::Unchecked);
}
}
ui.treeWidget->expandAll();//展开全部
connect(ui.treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(slotTreewidgetChange(QTreeWidgetItem*,int)));
}
void loadxmlTEST::updateTreewidget(QTreeWidgetItem *item)
{
//获取父节点
QTreeWidgetItem*parent = item->parent();
if (parent==nullptr)
{
return;
}
//获取子节点选中数量
int ischecked = 0;
int childCount = parent->childCount();
for (int i=0;i<childCount;i++)
{
if (parent->child(i)->checkState(0)==Qt::Checked)
{
ischecked++;
}
}
if (ischecked<=0)
{
parent->setCheckState(0, Qt::Unchecked);
}
else if (ischecked>=childCount)
{
parent->setCheckState(0, Qt::Checked);
}
else
{
parent->setCheckState(0, Qt::PartiallyChecked);
}
}
void loadxmlTEST::getTreewidgetData()
{
QTreeWidgetItemIterator it(ui.treeWidget);
ui.textBrowser->clear();
while (*it)
{
if ((*it)->checkState(0)==Qt::Checked)
{
QTreeWidgetItem *item = *it;
QString str = item->text(0);
str += item->text(1);
ui.textBrowser->append(str);
}
++it;
}
}
void loadxmlTEST::slotopenfile()
{
//打开文件,获取文件地址(多个)
/*QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("导入xml"), "../",
tr("xml文件 (*.xml;);;所有文件 (*.*)"));*/
//解析文件list
//if (fileNames.size() > 0)
//{
// for (auto fileitem : fileNames)
// {
// QString filePath = fileitem;
// //auto tmp = filePath.length();
// //auto rrr = filePath.lastIndexOf("/");
// QString fileName = filePath.right(filePath.length() - filePath.lastIndexOf("/") - 1);
// }
//}
//打开文件,单个
QString filenamexml = QFileDialog::getOpenFileName(this, tr("导入xml"), "../",
tr("xml(*.xml;);;所有文件(*.*)"));
//加载xml文件
loadxml(filenamexml);
initselectwidget();
}
void loadxmlTEST::slotTreewidgetChange(QTreeWidgetItem * item, int column)
{
//获取当前选中名称
QString strName = item->text(column);
int cnt = item->childCount();//子节点个数
if (cnt>0 && item->checkState(column)==Qt::Checked)
{
for (int i=0;i<cnt;i++)
{
item->child(column+i)->setCheckState(0,Qt::Checked);
}
}
else if (cnt>0 && item->checkState(column)==Qt::Unchecked)
{
for (int i=0;i<cnt;i++)
{
item->child(column + i)->setCheckState(0, Qt::Unchecked);
}
}
else
{
//更新上级选中状态
updateTreewidget(item);
}
}
注意事项:
1、QString filenamexml = QFileDialog::getOpenFileName(this, tr("导入xml"), "../",
tr("xml(*.xml;);;所有文件(*.*)"));
“ ”中的括号也需要用英文输入法,否则筛选无效或错误。