Qt代码实现解析xml文件<每个QDomElement带多个属性>到Qtreeview,使用MVC模式来实现QTreeView的项来增删改,并能使xml文件的QDomElement的属性跟随变化,完成编辑后实现flush(),并对文件进行重写
时间: 2023-12-14 10:40:01 浏览: 38
以下是一个简单的示例代码,演示了如何使用Qt的MVC模式来实现从XML文件加载数据到QTreeView中,并对其进行编辑和保存。
首先,我们需要创建一个QDomDocument对象并将其加载到XML文件中:
```cpp
QDomDocument doc("mydoc");
QFile file("myxml.xml");
if (!file.open(QIODevice::ReadOnly))
return;
if (!doc.setContent(&file)) {
file.close();
return;
}
file.close();
```
然后,我们可以获取根元素并使用QDomElement的子元素和属性来填充QStandardItemModel:
```cpp
QStandardItemModel *model = new QStandardItemModel();
QDomElement root = doc.documentElement();
QStandardItem *rootItem = new QStandardItem(root.tagName());
model->appendRow(rootItem);
for (QDomElement child = root.firstChildElement(); !child.isNull(); child = child.nextSiblingElement()) {
QStandardItem *childItem = new QStandardItem(child.tagName());
rootItem->appendRow(childItem);
for (QDomAttr attr = child.attributes().first(); !attr.isNull(); attr = attr.nextSibling()) {
QStandardItem *attrItem = new QStandardItem(attr.name());
QStandardItem *valueItem = new QStandardItem(attr.value());
childItem->appendRow(QList<QStandardItem*>() << attrItem << valueItem);
}
}
```
接下来,我们可以设置QTreeView以显示模型:
```cpp
QTreeView *treeView = new QTreeView();
treeView->setModel(model);
```
为了使元素属性能够随着编辑而变化,我们可以在QStandardItemModel中设置setData()函数:
```cpp
void MyStandardItemModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (role == Qt::EditRole) {
QStandardItemModel::setData(index, value, role);
QDomElement element = m_domElementList[index.row()];
if (index.column() == 0) {
element.setAttribute(value.toString(), element.attribute(m_headerList[0]));
element.removeAttribute(m_headerList[0]);
m_headerList[0] = value.toString();
}
else if (index.column() == 1) {
element.setAttribute(m_headerList[index.column()], value.toString());
}
}
}
```
在这个函数中,我们首先调用QStandardItemModel的setData()函数来更新视图,并使用QDomElement的setAttribute()和removeAttribute()函数来更新XML文件中的元素属性。对于第一列(即属性名称),我们还需要更新m_headerList以反映所做的更改。
最后,我们可以在窗口关闭时将更改保存回XML文件:
```cpp
void MainWindow::closeEvent(QCloseEvent *event)
{
QFile file("myxml.xml");
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
return;
QTextStream out(&file);
doc.save(out, 4);
file.close();
}
```
这样,我们就可以使用MVC模式从XML文件加载数据到QTreeView中,并对其进行编辑和保存。完整代码示例如下:
```cpp
#include <QtWidgets>
class MyStandardItemModel : public QStandardItemModel
{
public:
MyStandardItemModel(QDomElement root, QObject *parent = nullptr)
: QStandardItemModel(parent), m_root(root)
{
m_headerList << "Name" << "Value";
m_domElementList << root;
QStandardItem *rootItem = new QStandardItem(root.tagName());
appendRow(rootItem);
for (QDomElement child = root.firstChildElement(); !child.isNull(); child = child.nextSiblingElement()) {
m_domElementList << child;
QStandardItem *childItem = new QStandardItem(child.tagName());
rootItem->appendRow(childItem);
for (QDomAttr attr = child.attributes().first(); !attr.isNull(); attr = attr.nextSibling()) {
QStandardItem *attrItem = new QStandardItem(attr.name());
QStandardItem *valueItem = new QStandardItem(attr.value());
childItem->appendRow(QList<QStandardItem*>() << attrItem << valueItem);
}
}
}
void setData(const QModelIndex &index, const QVariant &value, int role) override
{
if (role == Qt::EditRole) {
QStandardItemModel::setData(index, value, role);
QDomElement element = m_domElementList[index.row()];
if (index.column() == 0) {
element.setAttribute(value.toString(), element.attribute(m_headerList[0]));
element.removeAttribute(m_headerList[0]);
m_headerList[0] = value.toString();
}
else if (index.column() == 1) {
element.setAttribute(m_headerList[index.column()], value.toString());
}
}
}
private:
QDomElement m_root;
QStringList m_headerList;
QList<QDomElement> m_domElementList;
};
class MainWindow : public QMainWindow
{
public:
MainWindow(QWidget *parent = nullptr)
: QMainWindow(parent)
{
QDomDocument doc("mydoc");
QFile file("myxml.xml");
if (!file.open(QIODevice::ReadOnly))
return;
if (!doc.setContent(&file)) {
file.close();
return;
}
file.close();
MyStandardItemModel *model = new MyStandardItemModel(doc.documentElement());
QTreeView *treeView = new QTreeView();
treeView->setModel(model);
setCentralWidget(treeView);
}
protected:
void closeEvent(QCloseEvent *event) override
{
QFile file("myxml.xml");
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
return;
QTextStream out(&file);
doc.save(out, 4);
file.close();
}
private:
QDomDocument doc;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
```