这与以前写的一篇文章类似:https://www.cnblogs.com/warmlight/p/12033459.html。不同的是这篇文章是读取xml文件,将xml 的tagname做为树节点的text,保存时完全按照树节点的text保存。
说明:首先在pro文件中 添加 QT += xml。对于本例子中的对话框中,一个树控件,两个按钮。如果想把示例中的xml信息完全放到树上,那就需要自己做点什么了。另外,加载xml文件时,是绝对路径。如果不知道怎么改,我觉得你需要回炉深造一下~~
不说太多了,把源码贴上去。
ManageTreeXml.cpp
1 #include "ManageTreeXml.h" 2 #include <QStack> 3 #include <QFile> 4 #include <QDebug> 5 6 #define TREE_LINK_TYPE "LINKPORT_TYPE" 7 #define TREE_PACKAGE_TYPE "PACKAGE_TYPE" 8 9 ManageTreeXml::ManageTreeXml() 10 { 11 //m_bXmlRoot = false; 12 } 13 14 bool ManageTreeXml::SaveTreeXml(QTreeWidget *pTree, QString xmlPath) 15 { 16 QDomDocument doc; 17 QDomProcessingInstruction head = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""); 18 doc.appendChild(head); 19 //invisibleRootItem()函数并不是得到我们想要的这个顶层节点,它得到的是所有节点的最终根节点,因此,得到顶层节点需要自己写操作,下面是根据任意一个节点获取其可见顶层节点的代码 20 QTreeWidgetItem *rootItem = pTree->invisibleRootItem(); //树的根节点 21 QTreeWidgetItem* childItem = rootItem->child(0); 22 23 QString strRoot; 24 strRoot = childItem->text(0); 25 QDomElement root = doc.createElement(strRoot); 26 doc.appendChild(root); 27 28 SaveItem(root, childItem, doc); 29 30 QFile file(xmlPath); 31 if (!file.open(QIODevice::WriteOnly)){ 32 return false; 33 } 34 QString xml = doc.toString(); 35 QTextStream txtOutput(&file); 36 txtOutput.setCodec("UTF-8"); 37 txtOutput<<xml; 38 file.close(); 39 40 return true; 41 } 42 43 bool ManageTreeXml::LoadTreeXml(QTreeWidget *pTree, QString xmlPath) 44 { 45 pTree->clear(); 46 47 if(xmlPath.isEmpty()) return false; 48 49 QDomDocument* doc = new QDomDocument; 50 QFile fl(xmlPath); 51 if(!doc->setContent(&fl)){ 52 fl.close(); 53 return false; 54 } 55 fl.close(); 56 57 showXml(pTree, doc,false); 58 59 return false; 60 } 61 62 bool ManageTreeXml::showXml(QTreeWidget* pTree, QDomDocument* pDoc, bool bEditable) 63 { 64 if(pDoc == NULL) return false; 65 66 // QDomNodeList RootLst = pDoc->elementsByTagName(XML_ROOT); 67 // QDomNode root = RootLst.item(0); 68 69 QDomElement docElem = pDoc->documentElement(); 70 71 QTreeWidgetItem* it = new QTreeWidgetItem; 72 if(bEditable){ 73 it->setFlags(Qt::ItemIsEditable|Qt::ItemIsEnabled|Qt::ItemIsSelectable); 74 } 75 // qDebug() << root.toElement().tagName(); 76 it->setText(0 ,docElem.tagName()); 77 pTree->addTopLevelItem(it); 78 79 showXmlTreeNode(pTree, docElem.firstChild() ,it, bEditable); 80 81 pTree->expandAll(); 82 return true; 83 } 84 85 bool ManageTreeXml::showXmlTreeNode(QTreeWidget* pTree, QDomNode domParent ,QTreeWidgetItem* treeParent, bool bEditable) 86 { 87 while(!domParent.isNull()){ 88 QTreeWidgetItem* it = new QTreeWidgetItem; 89 if(bEditable){ 90 it->setFlags(Qt::ItemIsEditable|Qt::ItemIsEnabled|Qt::ItemIsSelectable); 91 } 92 setTreeNodeText(domParent ,it); 93 treeParent->addChild(it); 94 if(domParent.hasChildNodes()){ 95 showXmlTreeNode(pTree, domParent.firstChild() ,it, bEditable); 96 } 97 domParent = domParent.nextSibling(); 98 } 99 return true; 100 } 101 102 void ManageTreeXml::setTreeNodeText(QDomNode Node ,QTreeWidgetItem* treeNode) 103 { 104 if(treeNode == NULL) return; 105 106 treeNode->setText(0 ,Node.toElement().tagName()); 107 // qDebug() << "ItemText:" << Node.toElement().tagName(); 108 109 QString treeType = TREE_PACKAGE_TYPE; 110 if(treeType == TREE_LINK_TYPE) 111 { 112 // treeNode->setText(1 ,Node.toElement().attribute("portName")); 113 // treeNode->setText(2 ,Node.toElement().attribute("portDesc")); 114 // treeNode->setText(3 ,Node.toElement().attribute("portType")); 115 // treeNode->setText(4 ,Node.toElement().attribute("portIP")); 116 // treeNode->setText(5 ,Node.toElement().attribute("portOrBaudRate")); 117 } 118 else if(treeType == TREE_PACKAGE_TYPE) 119 { 120 // treeNode->setText(1 ,Node.toElement().attribute("Value")); 121 // treeNode->setText(2 ,Node.toElement().attribute("Name")); 122 // treeNode->setText(3 ,Node.toElement().attribute("Index")); 123 // treeNode->setText(4 ,Node.toElement().attribute("Type")); 124 // treeNode->setText(5 ,Node.toElement().attribute("Len")); 125 // treeNode->setText(6 ,Node.toElement().attribute("Desc")); 126 } 127 } 128 129 130 void ManageTreeXml::SaveItem(QDomElement& root, QTreeWidgetItem *item, QDomDocument& doc) 131 { 132 int countChild = item->childCount(); 133 for (int i = 0; i < countChild; i++) 134 { 135 QTreeWidgetItem *childItem = item->child(i); 136 QString itemTxt = childItem->text(0); 137 QDomElement ele = doc.createElement(itemTxt); 138 root.appendChild(ele); 139 140 SaveItem(ele,childItem,doc); 141 } 142 }
ManageTreeXml.h
1 #ifndef MANAGETREEXML_H 2 #define MANAGETREEXML_H 3 #include <QTreeWidget> 4 #include <QDomDocument> 5 6 class ManageTreeXml 7 { 8 public: 9 ManageTreeXml(); 10 11 bool SaveTreeXml(QTreeWidget* pTree, QString xmlPath); 12 bool LoadTreeXml(QTreeWidget* pTree, QString xmlPath); 13 private: 14 bool showXml(QTreeWidget* pTree, QDomDocument *pDoc, bool bEditable); 15 bool showXmlTreeNode(QTreeWidget* pTree, QDomNode domParent, QTreeWidgetItem *treeParent, bool bEditable); 16 void setTreeNodeText(QDomNode Node, QTreeWidgetItem *treeNode); 17 18 void SaveItem(QDomElement& root,QTreeWidgetItem* item,QDomDocument& doc); 19 }; 20 21 #endif // MANAGETREEXML_H
DlgTreeXml.cpp
1 #include "DlgTreeXml.h" 2 #include "ui_DlgTreeXml.h" 3 #include "ManageTreeXml.h" 4 5 DlgTreeXml::DlgTreeXml(QWidget *parent) : 6 QDialog(parent), 7 ui(new Ui::DlgTreeXml) 8 { 9 ui->setupUi(this); 10 11 QStringList qv; 12 qv.push_back("标签");//qv.push_back("值");qv.push_back("名称");qv.push_back("索引");qv.push_back("类型");qv.push_back("长度");qv.push_back("描述"); 13 ui->treeWidget->setHeaderLabels(qv); 14 } 15 16 DlgTreeXml::~DlgTreeXml() 17 { 18 delete ui; 19 } 20 21 void DlgTreeXml::on_btnLoadXml_clicked() 22 { 23 LoadXml(); 24 } 25 26 void DlgTreeXml::on_btnSaveXml_clicked() 27 { 28 SaveXml(); 29 } 30 31 bool DlgTreeXml::LoadXml() 32 { 33 ManageTreeXml xml; 34 xml.LoadTreeXml(ui->treeWidget, "D:/_work/scenePro/1.xml"); 35 return false; 36 } 37 38 bool DlgTreeXml::SaveXml() 39 { 40 ManageTreeXml xml; 41 xml.SaveTreeXml(ui->treeWidget, "D:/_work/scenePro/2.xml"); 42 return false; 43 }
DlgTreeXml.h
1 #ifndef DLGTREEXML_H 2 #define DLGTREEXML_H 3 4 #include <QDialog> 5 6 namespace Ui { 7 class DlgTreeXml; 8 } 9 10 class DlgTreeXml : public QDialog 11 { 12 Q_OBJECT 13 14 public: 15 explicit DlgTreeXml(QWidget *parent = 0); 16 ~DlgTreeXml(); 17 18 private slots: 19 void on_btnLoadXml_clicked(); 20 21 void on_btnSaveXml_clicked(); 22 23 private: 24 Ui::DlgTreeXml *ui; 25 26 bool LoadXml(); 27 bool SaveXml(); 28 }; 29 30 #endif // DLGTREEXML_H
示例xml
1 <?xml version='1.0' encoding='UTF-8'?> 2 <MyItem> 3 <Package Head="check" Desc="" Name="接收数据" Id="9"> 4 <Field Desc="经度" Value="118.244" Type="Float" Name="经度"/> 5 <Field Desc="纬度" Value="42.078105" Type="Float" Name="纬度"/> 6 <Field Desc="高度" Value="8.8" Type="Float" Name="高度"/> 7 <Field Desc="高度1" Value="184.8" Type="Float" Name="高度1"/> 8 </Package> 9 <Package Head="check" Desc="" Name="校正数据" Id="10"> 10 <Field Desc="经度" Value="116.244945" Type="Float" Name="经度"/> 11 <Field Desc="纬度" Value="40.078105" Type="Float" Name="纬度"/> 12 <Field Desc="高度" Value="10.8" Type="Float" Name="高度"/> 13 </Package> 14 <Package Head="send" Desc="" Name="发送数据" Id="11"> 15 <Field Desc="经度" Value="116.244945" Type="Float" Name="经度"> 16 <SubField Desc="则经度" Value="116.244945" Type="Float" Name="经度"> 17 <SubField Desc="zizi经度" Value="116.244945" Type="Float" Name="经度"/> 18 <SubField11 Desc="则经度" Value="116.244945" Type="Float" Name="经度"/> 19 </SubField> 20 </Field> 21 <Field Desc="纬度" Value="40.078105" Type="Float" Name="纬度"/> 22 <Field Desc="高度" Value="10.8" Type="Float" Name="高度"/> 23 </Package> 24 </MyItem>
生成的xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <MyItem> 3 <Package> 4 <Field/> 5 <Field/> 6 <Field/> 7 <Field/> 8 </Package> 9 <Package> 10 <Field/> 11 <Field/> 12 <Field/> 13 </Package> 14 <Package> 15 <Field> 16 <SubField> 17 <SubField/> 18 <SubField11/> 19 </SubField> 20 </Field> 21 <Field/> 22 <Field/> 23 </Package> 24 </MyItem>