Qt代码实现解析xml文件到Qtreeview,使用MVC模式中的模型model来控制QTreeView的展示内容,使用QTreeView中的项的右键菜单信号来实现model的增删改操作,将model的更改也能体现到xml文件中
时间: 2023-12-14 17:39:30 浏览: 156
QT QTreewidget显示和修改xml文件并导出
以下是一个简单的示例代码来解析xml文件到QTreeView中,并使用MVC模式中的模型来控制QTreeView的展示内容,并且使用QTreeView中的项的右键菜单信号来实现model的增删改操作,并将model的更改也能体现到xml文件中。
首先需要在头文件中引入以下库:
```cpp
#include <QTreeView>
#include <QStandardItemModel>
#include <QMenu>
#include <QAction>
#include <QFile>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
```
然后在类中声明以下变量:
```cpp
private:
QTreeView* m_treeView;
QStandardItemModel* m_model;
QMenu* m_menu;
QAction* m_addAction;
QAction* m_removeAction;
QAction* m_modifyAction;
QFile* m_file;
```
在构造函数中初始化这些变量:
```cpp
m_treeView = new QTreeView(this);
m_model = new QStandardItemModel(this);
m_treeView->setModel(m_model);
m_addAction = new QAction(tr("Add"), this);
m_removeAction = new QAction(tr("Remove"), this);
m_modifyAction = new QAction(tr("Modify"), this);
m_menu = new QMenu(this);
m_menu->addAction(m_addAction);
m_menu->addAction(m_removeAction);
m_menu->addAction(m_modifyAction);
m_file = new QFile("data.xml");
if(!m_file->open(QIODevice::ReadWrite | QIODevice::Text)) {
qDebug() << "Open file failed!";
}
else {
QXmlStreamReader reader(m_file);
while(!reader.atEnd() && !reader.hasError()) {
QXmlStreamReader::TokenType token = reader.readNext();
if(token == QXmlStreamReader::StartDocument) {
continue;
}
if(token == QXmlStreamReader::StartElement) {
if(reader.name() == "root") {
continue;
}
if(reader.name() == "item") {
QStandardItem* item = new QStandardItem(reader.attributes().value("name").toString());
m_model->appendRow(item);
}
}
}
reader.clear();
}
```
这段代码中,我们创建了一个QTreeView和一个QStandardItemModel,并将其关联起来。然后创建了一个QMenu,并在其中添加了三个QAction。最后,我们创建了一个QFile用于读取和写入xml文件,并使用QXmlStreamReader读取xml文件中的数据,并将其添加到QStandardItemModel中。
接下来,我们需要实现右键菜单信号的槽函数:
```cpp
void onCustomContextMenuRequested(const QPoint& pos) {
QModelIndex index = m_treeView->indexAt(pos);
if(!index.isValid()) {
return;
}
m_menu->exec(m_treeView->viewport()->mapToGlobal(pos));
}
void onAddActionTriggered() {
QStandardItem* item = new QStandardItem("New Item");
m_model->appendRow(item);
QXmlStreamWriter writer(m_file);
writer.setAutoFormatting(true);
writer.writeStartElement("item");
writer.writeAttribute("name", "New Item");
writer.writeEndElement();
m_file->flush();
}
void onRemoveActionTriggered() {
QModelIndex index = m_treeView->currentIndex();
m_model->removeRow(index.row());
QXmlStreamReader reader(m_file);
QXmlStreamWriter writer(m_file);
writer.setAutoFormatting(true);
writer.writeStartElement("root");
while(!reader.atEnd() && !reader.hasError()) {
QXmlStreamReader::TokenType token = reader.readNext();
if(token == QXmlStreamReader::StartElement) {
if(reader.name() == "item") {
if(reader.attributes().value("name").toString() != m_model->item(index.row())->text()) {
writer.writeStartElement("item");
writer.writeAttribute("name", reader.attributes().value("name").toString());
writer.writeEndElement();
}
}
}
}
writer.writeEndElement();
m_file->flush();
}
void onModifyActionTriggered() {
QModelIndex index = m_treeView->currentIndex();
m_model->item(index.row())->setText("Modified Item");
QXmlStreamReader reader(m_file);
QXmlStreamWriter writer(m_file);
writer.setAutoFormatting(true);
writer.writeStartElement("root");
while(!reader.atEnd() && !reader.hasError()) {
QXmlStreamReader::TokenType token = reader.readNext();
if(token == QXmlStreamReader::StartElement) {
if(reader.name() == "item") {
if(reader.attributes().value("name").toString() != m_model->item(index.row())->text()) {
writer.writeStartElement("item");
writer.writeAttribute("name", reader.attributes().value("name").toString());
writer.writeEndElement();
}
else {
writer.writeStartElement("item");
writer.writeAttribute("name", "Modified Item");
writer.writeEndElement();
}
}
}
}
writer.writeEndElement();
m_file->flush();
}
```
这段代码中,我们首先实现了一个槽函数来响应QTreeView的右键菜单信号,并在其中判断当前选中的项是否有效。然后我们实现了三个槽函数来响应QAction的触发信号。在onAddActionTriggered中,我们创建了一个新的QStandardItem,并将其添加到QStandardItemModel中,并使用QXmlStreamWriter将其写入xml文件中。在onRemoveActionTriggered中,我们首先删除了QStandardItemModel中的当前选中项,然后使用QXmlStreamReader和QXmlStreamWriter将xml文件中的相应项删除。在onModifyActionTriggered中,我们首先修改了QStandardItemModel中的当前选中项的文本,然后使用QXmlStreamReader和QXmlStreamWriter将xml文件中的相应项修改。
最后,我们需要在类中添加信号和槽的连接:
```cpp
connect(m_treeView, &QTreeView::customContextMenuRequested, this, &MainWindow::onCustomContextMenuRequested);
connect(m_addAction, &QAction::triggered, this, &MainWindow::onAddActionTriggered);
connect(m_removeAction, &QAction::triggered, this, &MainWindow::onRemoveActionTriggered);
connect(m_modifyAction, &QAction::triggered, this, &MainWindow::onModifyActionTriggered);
```
这段代码中,我们将QTreeView的customContextMenuRequested信号连接到onCustomContextMenuRequested槽函数上,将QAction的triggered信号连接到对应的槽函数上。
阅读全文