QTreeWidget 挂上自定义结构体 (setData)

上篇文章(https://www.cnblogs.com/warmlight/p/12964166.html)说,如果想把示例中的xml信息完全放到树上,那就需要自己做点什么了。那到底要怎么做呢?这里再讨论一下。

示例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>
View Code

 

QTreeWidget导出xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <MyItem>
 3     <Package Name="接收数据" Id="9" Head="check" Desc="">
 4         <Field Name="经度" Value="118.244" Desc="经度" Type="Float"/>
 5         <Field Name="纬度" Value="42.078105" Desc="纬度" Type="Float"/>
 6         <Field Name="高度" Value="8.8" Desc="高度" Type="Float"/>
 7         <Field Name="高度1" Value="184.8" Desc="高度1" Type="Float"/>
 8     </Package>
 9     <Package Name="校正数据" Id="10" Head="check" Desc="">
10         <Field Name="经度" Value="116.244945" Desc="经度" Type="Float"/>
11         <Field Name="纬度" Value="40.078105" Desc="纬度" Type="Float"/>
12         <Field Name="高度" Value="10.8" Desc="高度" Type="Float"/>
13     </Package>
14     <Package Name="发送数据" Id="11" Head="send" Desc="">
15         <Field Name="经度" Value="116.244945" Desc="经度" Type="Float">
16             <SubField Name="经度" Value="116.244945" Desc="则经度" Type="Float">
17                 <SubField Name="经度" Value="116.244945" Desc="zizi经度" Type="Float"/>
18                 <SubField11 Name="经度" Value="116.244945" Desc="则经度" Type="Float"/>
19             </SubField>
20         </Field>
21         <Field Name="纬度" Value="40.078105" Desc="纬度" Type="Float"/>
22         <Field Name="高度" Value="10.8" Desc="高度" Type="Float"/>
23     </Package>
24 </MyItem>
View Code

 

我没观察一下原xml,根节点无属性,其他节点的属性也比较单一,分为两种。那就定义两个结构体吧。如果你的节点有更多的属性,我想你就要考虑是不是换其他方法了。

在ManageTreeXml.h中,添加两个结构体:

 1 struct PackageItem : public QObjectUserData {
 2     QString head;
 3     QString name;
 4     QString desc;
 5     QString id;
 6 };
 7 Q_DECLARE_METATYPE(PackageItem)
 8 
 9 struct FieldItem : public QObjectUserData {
10     QString desc;
11     QString name;
12     QString value;
13     QString type;
14 };
15 Q_DECLARE_METATYPE(FieldItem)

一定要注意使用Q_DECLARE_METATYPE宏。

这里是在基础代码上增加的。基础代码和请查看:https://www.cnblogs.com/warmlight/p/12964166.html

加载xml文件时,需要做一些处理。这里修改SetTreeNodeText函数

 1 void ManageTreeXml::setTreeNodeText(QDomNode Node ,QTreeWidgetItem* treeNode)
 2 {
 3     if(treeNode == NULL)    return;
 4 
 5     QDomElement nodeEle = Node.toElement();
 6     QString tagName =nodeEle.tagName();
 7     treeNode->setText(0 ,tagName);
 8     if(tagName.compare("Package") == 0){
 9         PackageItem item;
10         item.desc = nodeEle.attribute("Desc");
11         item.head = nodeEle.attribute("Head");
12         item.id = nodeEle.attribute("Id");
13         item.name = nodeEle.attribute("Name");
14         treeNode->setData(0, Qt::UserRole + 1, QVariant::fromValue(item));
15     }
16     else if(tagName.compare("Field") == 0 ||
17             tagName.compare("SubField") == 0 ||
18             tagName.compare("SubField11") == 0){
19         FieldItem item;
20         item.desc = nodeEle.attribute("Desc");
21         item.value = nodeEle.attribute("Value");
22         item.type = nodeEle.attribute("Type");
23         item.name = nodeEle.attribute("Name");
24         treeNode->setData(0, Qt::UserRole + 1, QVariant::fromValue(item));
25     }
26 //    qDebug() << "ItemText:" << Node.toElement().tagName();
27 
28     QString treeType = TREE_PACKAGE_TYPE;
29     if(treeType == TREE_LINK_TYPE)
30     {
31 //        treeNode->setText(1 ,Node.toElement().attribute("portName"));
32 //        treeNode->setText(2 ,Node.toElement().attribute("portDesc"));
33 //        treeNode->setText(3 ,Node.toElement().attribute("portType"));
34 //        treeNode->setText(4 ,Node.toElement().attribute("portIP"));
35 //        treeNode->setText(5 ,Node.toElement().attribute("portOrBaudRate"));
36     }
37     else if(treeType == TREE_PACKAGE_TYPE)
38     {
39 //        treeNode->setText(1 ,Node.toElement().attribute("Value"));
40 //        treeNode->setText(2 ,Node.toElement().attribute("Name"));
41 //        treeNode->setText(3 ,Node.toElement().attribute("Index"));
42 //        treeNode->setText(4 ,Node.toElement().attribute("Type"));
43 //        treeNode->setText(5 ,Node.toElement().attribute("Len"));
44 //        treeNode->setText(6 ,Node.toElement().attribute("Desc"));
45     }
46 }
View Code

保存xml文件时,增加函数SetDomEleAttribute,并在SaveItem中调用。

 1 void ManageTreeXml::SaveItem(QDomElement& root, QTreeWidgetItem *item, QDomDocument& doc)
 2 {
 3     int countChild = item->childCount();
 4     for (int i = 0; i < countChild; i++)
 5     {
 6         QTreeWidgetItem *childItem = item->child(i);
 7         QString itemTxt = childItem->text(0);
 8         QDomElement ele = doc.createElement(itemTxt);
 9         SetDomEleAttribute(ele, childItem);
10         root.appendChild(ele);
11 
12         SaveItem(ele,childItem,doc);
13     }
14 }
15 
16 void ManageTreeXml::SetDomEleAttribute(QDomElement &ele, QTreeWidgetItem *item)
17 {
18     QString itemTxt = item->text(0);
19     if(itemTxt.compare("Package") == 0){
20         PackageItem packItem = item->data(0, Qt::UserRole + 1).value<PackageItem>();
21         ele.setAttribute("Head", packItem.head);
22         ele.setAttribute("Desc", packItem.desc);
23         ele.setAttribute("Name", packItem.name);
24         ele.setAttribute("Id", packItem.id);
25     }
26     else if (itemTxt.compare("Field") == 0 ||
27              itemTxt.compare("SubField") == 0 ||
28              itemTxt.compare("SubField11") == 0 ) {
29         FieldItem fieldItem = item->data(0, Qt::UserRole + 1).value<FieldItem>();
30         ele.setAttribute("Value", fieldItem.value);
31         ele.setAttribute("Desc", fieldItem.desc);
32         ele.setAttribute("Name", fieldItem.name);
33         ele.setAttribute("Type", fieldItem.type);
34     }
35 }
View Code

这样保存的xml和源xml就完全一致了。

xml文件不同的话,要根据个人情况修改。

posted @ 2020-05-27 16:40  阳光下的小土豆  阅读(4297)  评论(0编辑  收藏  举报