QTreeWidget 保存和显示xml文件
这与以前写的一篇文章类似:https://www.cnblogs.com/warmlight/p/12033459.html。不同的是这篇文章是读取xml文件,将xml 的tagname做为树节点的text,保存时完全按照树节点的text保存。
说明:首先在pro文件中 添加 QT += xml。对于本例子中的对话框中,一个树控件,两个按钮。如果想把示例中的xml信息完全放到树上,那就需要自己做点什么了。另外,加载xml文件时,是绝对路径。如果不知道怎么改,我觉得你需要回炉深造一下~~
不说太多了,把源码贴上去。
ManageTreeXml.cpp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 } 12 13 bool ManageTreeXml::SaveTreeXml(QTreeWidget *pTree, QString xmlPath) 14 { 15 QDomDocument doc; 16 QDomProcessingInstruction head = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""); 17 doc.appendChild(head); 18 //invisibleRootItem()函数并不是得到我们想要的这个顶层节点,它得到的是所有节点的最终根节点,因此,得到顶层节点需要自己写操作,下面是根据任意一个节点获取其可见顶层节点的代码 19 QTreeWidgetItem *rootItem = pTree->invisibleRootItem(); //树的根节点 20 QTreeWidgetItem* childItem = rootItem->child(0); 21 22 QString strRoot; 23 strRoot = childItem->text(0); 24 QDomElement root = doc.createElement(strRoot); 25 doc.appendChild(root); 26 27 SaveItem(root, childItem, doc); 28 29 QFile file(xmlPath); 30 if (!file.open(QIODevice::WriteOnly)){ 31 return false; 32 } 33 QString xml = doc.toString(); 34 QTextStream txtOutput(&file); 35 txtOutput.setCodec("UTF-8"); 36 txtOutput<<xml; 37 file.close(); 38 39 return true; 40 } 41 42 bool ManageTreeXml::LoadTreeXml(QTreeWidget *pTree, QString xmlPath) 43 { 44 pTree->clear(); 45 46 if(xmlPath.isEmpty()) return false; 47 48 QDomDocument* doc = new QDomDocument; 49 QFile fl(xmlPath); 50 if(!doc->setContent(&fl)){ 51 fl.close(); 52 return false; 53 } 54 fl.close(); 55 56 showXml(pTree, doc,false); 57 58 return false; 59 } 60 61 bool ManageTreeXml::showXml(QTreeWidget* pTree, QDomDocument* pDoc, bool bEditable) 62 { 63 if(pDoc == NULL) return false; 64 65 // QDomNodeList RootLst = pDoc->elementsByTagName(XML_ROOT); 66 // QDomNode root = RootLst.item(0); 67 68 QDomElement docElem = pDoc->documentElement(); 69 70 QTreeWidgetItem* it = new QTreeWidgetItem; 71 if(bEditable){ 72 it->setFlags(Qt::ItemIsEditable|Qt::ItemIsEnabled|Qt::ItemIsSelectable); 73 } 74 // qDebug() << root.toElement().tagName(); 75 it->setText(0 ,docElem.tagName()); 76 pTree->addTopLevelItem(it); 77 78 showXmlTreeNode(pTree, docElem.firstChild() ,it, bEditable); 79 80 pTree->expandAll(); 81 return true; 82 } 83 84 bool ManageTreeXml::showXmlTreeNode(QTreeWidget* pTree, QDomNode domParent ,QTreeWidgetItem* treeParent, bool bEditable) 85 { 86 while(!domParent.isNull()){ 87 QTreeWidgetItem* it = new QTreeWidgetItem; 88 if(bEditable){ 89 it->setFlags(Qt::ItemIsEditable|Qt::ItemIsEnabled|Qt::ItemIsSelectable); 90 } 91 setTreeNodeText(domParent ,it); 92 treeParent->addChild(it); 93 if(domParent.hasChildNodes()){ 94 showXmlTreeNode(pTree, domParent.firstChild() ,it, bEditable); 95 } 96 domParent = domParent.nextSibling(); 97 } 98 return true; 99 } 100 101 void ManageTreeXml::setTreeNodeText(QDomNode Node ,QTreeWidgetItem* treeNode) 102 { 103 if(treeNode == NULL) return; 104 105 treeNode->setText(0 ,Node.toElement().tagName()); 106 // qDebug() << "ItemText:" << Node.toElement().tagName(); 107 108 QString treeType = TREE_PACKAGE_TYPE; 109 if(treeType == TREE_LINK_TYPE) 110 { 111 // treeNode->setText(1 ,Node.toElement().attribute("portName")); 112 // treeNode->setText(2 ,Node.toElement().attribute("portDesc")); 113 // treeNode->setText(3 ,Node.toElement().attribute("portType")); 114 // treeNode->setText(4 ,Node.toElement().attribute("portIP")); 115 // treeNode->setText(5 ,Node.toElement().attribute("portOrBaudRate")); 116 } 117 else if(treeType == TREE_PACKAGE_TYPE) 118 { 119 // treeNode->setText(1 ,Node.toElement().attribute("Value")); 120 // treeNode->setText(2 ,Node.toElement().attribute("Name")); 121 // treeNode->setText(3 ,Node.toElement().attribute("Index")); 122 // treeNode->setText(4 ,Node.toElement().attribute("Type")); 123 // treeNode->setText(5 ,Node.toElement().attribute("Len")); 124 // treeNode->setText(6 ,Node.toElement().attribute("Desc")); 125 } 126 } 127 128 129 void ManageTreeXml::SaveItem(QDomElement& root, QTreeWidgetItem *item, QDomDocument& doc) 130 { 131 int countChild = item->childCount(); 132 for (int i = 0; i < countChild; i++) 133 { 134 QTreeWidgetItem *childItem = item->child(i); 135 QString itemTxt = childItem->text(0); 136 QDomElement ele = doc.createElement(itemTxt); 137 root.appendChild(ele); 138 139 SaveItem(ele,childItem,doc); 140 } 141 }
ManageTreeXml.h
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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(如果想将示例xml的信息全部挂到树上,请查阅:https://www.cnblogs.com/warmlight/p/12974114.html)
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>