qtreewidget 显示保存xml文件
此文是读取和存储已知结构的xml,对于未知结构的xml,可以用递归方法读取和遍历。可参考文章:Qt遍历不规则树的节点。
1、QTreewidget设置
//折叠图标(三角图标)换成自定义图标 ui->treeWidget->setStyleSheet("QTreeView::branch:has-children:!has-siblings:closed,\ QTreeView::branch:closed:has-children:has-siblings{border-image: none; image: url(:/images/plus.png);}\ QTreeView::branch:open:has-children:!has-siblings,\ QTreeView::branch:open:has-children:has-siblings{border-image: none; image: url(:/images/minus.png);}");
2、显示保存xml
头文件
#ifndef PROCESSDEVICEXML_H #define PROCESSDEVICEXML_H #include <QObject> #include <QDomElement> #include <QTreeWidget> #include "public.h" #define ManageDeviceStr "ManageDevice" #define SystemStr "System" #define SubSystemStr "SubSystem" #define DeviceStr "Device" #define NameStr "name" #define TypeStr "type" #define DeviceXmlName "DeviceItem.xml" class ProcessDeviceXml : public QObject { Q_OBJECT public: explicit ProcessDeviceXml(QObject *parent = nullptr); bool OpenXml(QString fileName, QList<DeviceInfo>& listDev, QTreeWidget* pTreeWg = NULL); void ShowXml(QDomElement &docElem, QList<DeviceInfo> &listDev, QTreeWidget *treeWg); bool SaveXML(QString fileName, QTreeWidget *pTreeWg); bool AddTreeItem(QTreeWidget *pTreeWg, QTreeWidgetItem *clickedItem, int itemType); bool delTreeItem(QTreeWidget *pTreeWg, QTreeWidgetItem *clickedItem, int nType); signals: public slots: private: }; #endif // PROCESSDEVICEXML_H
源文件:
显示图标时,要换成自己的图标路径;如果出现编译不通过,需要根据情况修改一下。
#include "processdevicexml.h" #include <QTextStream> #include <QMessageBox> #include <QFile> #include <QDebug> #include "public.h" #include "adddevicedlg.h" #include "extern.h" ProcessDeviceXml::ProcessDeviceXml(QObject *parent) : QObject(parent) { } bool ProcessDeviceXml::OpenXml(QString fileName, QList<DeviceInfo>& listDeviceName, QTreeWidget* pTreeWg) { QFile file(fileName); if (file.open(QIODevice::ReadOnly)) { QDomDocument dom; QString errorStr; int errorLine; int errorCol; if (!dom.setContent(&file, true, &errorStr, &errorLine, &errorCol)) { qDebug() << errorStr << "line: " << errorLine << "col: " << errorCol; file.close(); return false; } else { pTreeWg->clear(); QDomElement docElem = dom.documentElement(); ShowXml(docElem, listDeviceName, pTreeWg); pTreeWg->expandAll(); } file.close(); return true; } else { file.close(); return false; } } void ProcessDeviceXml::ShowXml(QDomElement& docElem, QList<DeviceInfo>& listDev, QTreeWidget* treeWg) { //根节点 QTreeWidgetItem *projectItem = new QTreeWidgetItem(treeWg); QString projectName = docElem.attribute(NameStr); projectItem->setText(0, projectName); projectItem->setData(0, Qt::UserRole, QString::number(TypeProject)); projectItem->setIcon(0, QIcon(QStringLiteral(":/image/system.png"))); projectItem->setWhatsThis(0, SystemStr); listDev.clear(); QDomNode systemNode = docElem.firstChild(); while (!systemNode.isNull()) { DeviceInfo devInfo; devInfo.listDevName.clear(); QDomElement elementSystem = systemNode.toElement(); // try to convert the node to an element. if (elementSystem.tagName() == QStringLiteral(SystemStr)) { QTreeWidgetItem *systemItem = new QTreeWidgetItem(projectItem); //系统节点 QString strSystemName = elementSystem.attribute(NameStr); devInfo.qstrSystemName = strSystemName; systemItem->setText(0, strSystemName); systemItem->setData(0, Qt::UserRole, QString::number(TypeSystem)); systemItem->setIcon(0, QIcon(QStringLiteral(":/image/system.png"))); systemItem->setWhatsThis(0, SystemStr); //子系统节点 QDomNode subsystemNode = systemNode.firstChild(); while (!subsystemNode.isNull()) { QDomElement elementDev = subsystemNode.toElement(); if (elementDev.tagName() == QStringLiteral(SubSystemStr)) { QString strDevName = elementDev.attribute(NameStr); QTreeWidgetItem *subsystemItem = new QTreeWidgetItem(systemItem); subsystemItem->setText(0, strDevName); subsystemItem->setIcon(0, QIcon(QStringLiteral(":/image/subSystem.png"))); subsystemItem->setData(0, Qt::UserRole, QString::number(TypeSubsystem)); subsystemItem->setWhatsThis(0, SubSystemStr); QDomNode devNode = subsystemNode.firstChild(); while (!devNode.isNull()) { QDomElement elementDev = devNode.toElement(); if (elementDev.tagName() == QStringLiteral(DeviceStr)) { QString strDevName = elementDev.attribute(NameStr); QTreeWidgetItem *devItem = new QTreeWidgetItem(subsystemItem); devItem->setText(0, strDevName); devItem->setIcon(0, QIcon(QStringLiteral(":/Qimage/device.png"))); devItem->setWhatsThis(0, DeviceStr); devItem->setData(0, Qt::UserRole, QString::number(TypeDevice)); devInfo.listDevName.push_back(strDevName); } devNode = devNode.nextSibling(); } } subsystemNode = subsystemNode.nextSibling(); } } //下一个分组节点 listDev.push_back(devInfo); systemNode = systemNode.nextSibling(); } return; } bool ProcessDeviceXml::SaveXML(QString fileName, QTreeWidget* pTreeWg) { QTreeWidgetItem *rootItem = pTreeWg->invisibleRootItem(); //树的根节点 int countSystem = rootItem->childCount(); if (countSystem <= 0) //列表树没有项 { return false; } QFile db(fileName); if (!db.open(QIODevice::WriteOnly | QIODevice::Truncate)) return false; //只写方式打开,并清空以前的信息 QDomDocument doc; QDomProcessingInstruction instruction; instruction = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""); doc.appendChild(instruction); QDomElement root = doc.createElement(ManageDeviceStr); QString projectName = p_globalObject->getProjectName(); QDomAttr elementProjAttr = doc.createAttribute(NameStr); elementProjAttr.setValue(projectName); root.setAttributeNode(elementProjAttr); doc.appendChild(root); //添加根元素 QTreeWidgetItem* projectItem = rootItem->child(0); countSystem = projectItem->childCount(); for (int i = 0; i < countSystem; i++) { QTreeWidgetItem *systemItem = projectItem->child(i); QString systemName = systemItem->text(0); QDomElement elementSystem = doc.createElement(SystemStr); QDomAttr elementSystemAttr = doc.createAttribute(NameStr); elementSystemAttr.setValue(systemName); elementSystem.setAttributeNode(elementSystemAttr); root.appendChild(elementSystem); int countSubsystem = systemItem->childCount(); for (int j = 0; j < countSubsystem; j++) { QTreeWidgetItem *subsystemItem = systemItem->child(j); QDomElement elementSubsystem = doc.createElement(SubSystemStr); //子系统项属性name QString subsystemName = subsystemItem->text(0); QDomAttr elementSubsystemNameAttr = doc.createAttribute(NameStr); elementSubsystemNameAttr.setValue(subsystemName); elementSubsystem.setAttributeNode(elementSubsystemNameAttr); elementSystem.appendChild(elementSubsystem); int coutDev = subsystemItem->childCount(); for (int k = 0; k < coutDev; k++) { QTreeWidgetItem *devItem = subsystemItem->child(k); QString devName = devItem->text(0); QDomElement elementChn = doc.createElement(DeviceStr); QDomAttr elementChnAttr = doc.createAttribute(NameStr); elementChnAttr.setValue(devName); elementChn.setAttributeNode(elementChnAttr); elementSubsystem.appendChild(elementChn); } } } QTextStream out(&db); out.setCodec("UTF-8"); doc.save(out, 4); db.close(); return true; } bool ProcessDeviceXml::AddTreeItem(QTreeWidget* pTreeWg, QTreeWidgetItem* clickedItem, int itemType) { QString qstrCaption; int nType = TypeDevice; switch (itemType) { case TypeProject://添加系统 qstrCaption = "添加系统"; nType = TypeSystem; break; case TypeSystem://添加分系统 qstrCaption = "添加子系统"; nType = TypeSubsystem; break; case TypeSubsystem://添加设备 case TypeDevice: qstrCaption = "添加设备"; nType = TypeDevice; break; default: break; } AddDeviceDlg dlg; dlg.SetCaption(qstrCaption); if(dlg.exec() == QDialog::Rejected){ return false; } QString txt = dlg.GetTxt(); QTreeWidgetItem *item = new QTreeWidgetItem(clickedItem); item->setText(0, txt); item->setData(0, Qt::UserRole, QString::number(nType)); item->setIcon(0, QIcon(QStringLiteral(":image/group.png"))); item->setWhatsThis(0, qstrCaption); pTreeWg->expandItem(clickedItem); return true; }