Qt 6.12 LTS is out! See what's new in the release
blog
How to select the text in the tree view to change the properties in QDOM model tree which generated from XML?
-
I want my items to be highlighted or change to blue like when we select multiple items using CTRL key.
DomItem.cpp #include "DOMItem.h" #include<QCheckBox> #include <QtXml> //! [0] DomItem::DomItem(const QDomNode &node, int row, DomItem *parent) : domNode(node), //! [0] // Record the item's location within its parent. //! [1] parentItem(parent), rowNumber(row) {} //! [1] //! [2] DomItem::~DomItem() { qDeleteAll(childItems); } //! [2] //! [3] QDomNode DomItem::node() const { return domNode; } //! [3] //! [4] DomItem *DomItem::parent() { return parentItem; } //! [4] //! [5] DomItem *DomItem::child(int i) { DomItem *childItem = childItems.value(i); if (childItem) return childItem; // if child does not yet exist, create it if (i >= 0 && i < domNode.childNodes().count()) { QDomNode childNode = domNode.childNodes().item(i); childItem = new DomItem(childNode, i, this); childItems[i] = childItem; } return childItem; } //! [5] //! [6] int DomItem::row() const { return rowNumber; } //! [6] QVariant DomItem::data(int column) const { return itemData.value(column); }DomModel.cpp #include "DomModel.h" #include "DOMItem.h" //#include "mainwindow.h" #include <QtXml> //! [0] DomModel::DomModel(const QDomDocument &document, QObject *parent) : QAbstractItemModel(parent), domDocument(document), rootItem(new DomItem(domDocument, 0)) { } //! [0] //! [1] DomModel::~DomModel() { delete rootItem; } //! [1] //! [2] int DomModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); return 3; } //! [2] QVariant DomModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); DomItem *item = static_cast<DomItem*>(index.internalPointer()); const QDomNode node = item->node(); //if ( role == Qt::CheckStateRole && index.column() == 0 ) if ( role == Qt::CheckStateRole && !index.parent().isValid()) return static_cast< int >( item->isChecked() ? Qt::Checked : Qt::Unchecked ); if (role != Qt::DisplayRole) return QVariant(); switch (index.column()) { case 0: return node.nodeName(); case 1: { const QDomNamedNodeMap attributeMap = node.attributes(); QStringList attributes; for (int i = 0; i < attributeMap.count(); ++i) { QDomNode attribute = attributeMap.item(i); attributes << attribute.nodeName() + "=\"" + attribute.nodeValue() + '"'; } return attributes.join(' '); } case 2: return node.nodeValue().split('\n').join(' '); default: break; } return item->data(index.column()); } Qt::ItemFlags DomModel::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::NoItemFlags; Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; if ( index.column() == 0 ) flags |= Qt::ItemIsUserCheckable; return flags; } //! [6] QVariant DomModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { switch (section) { case 0: return tr("Name"); case 1: return tr("Attributes"); case 2: return tr("Value"); default: break; } } return QVariant(); } //! [6] //! [7] QModelIndex DomModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); DomItem *parentItem; if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast<DomItem*>(parent.internalPointer()); //! [7] //! [8] DomItem *childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); return QModelIndex(); } //! [8] //! [9] QModelIndex DomModel::parent(const QModelIndex &child) const { if (!child.isValid()) return QModelIndex(); DomItem *childItem = static_cast<DomItem*>(child.internalPointer()); DomItem *parentItem = childItem->parent(); if (!parentItem || parentItem == rootItem) return QModelIndex(); return createIndex(parentItem->row(), 0, parentItem); } //! [9] //! [10] int DomModel::rowCount(const QModelIndex &parent) const { if (parent.column() > 0) return 0; DomItem *parentItem; if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast<DomItem*>(parent.internalPointer()); return parentItem->node().childNodes().count(); } //! [10] //! bool DomModel::setData(const QModelIndex &index, const QVariant &value, int role) { DomItem *item = static_cast<DomItem*>(index.internalPointer()); if (index.column() == 0 ){ if (role == Qt::EditRole) { return false; } if (role == Qt::CheckStateRole) { item->setChecked(value.toBool()); emit dataChanged(index, index); return true; } } return QAbstractItemModel::setData(index, value, role); }mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include "DomModel.h" #include <QDomDocument> #include <QTreeView> #include <QMenuBar> #include <QFileDialog> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), model(new DomModel(QDomDocument(), this)), view(new QTreeView(this)) { fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(tr("&Open..."), this, &MainWindow::openFile, QKeySequence::Open); fileMenu->addAction(tr("E&xit"), this, &QWidget::close, QKeySequence::Quit); view->setModel(model); setCentralWidget(view); setWindowTitle(tr("QTreeViewXML")); } void MainWindow::openFile() { QString filePath = QFileDialog::getOpenFileName(this, tr("Open File"), xmlPath, tr("XML files (*.xml);;HTML files (*.html);;" "SVG files (*.svg);;User Interface files (*.ui)")); if (!filePath.isEmpty()) { QFile file(filePath); if (file.open(QIODevice::ReadOnly)) { QDomDocument document; if (document.setContent(&file)) { DomModel *newModel = new DomModel(document, this); view->setModel(newModel); delete model; model = newModel; xmlPath = filePath; } file.close(); } } }