DOM Bookmarks Anwendung
Bietet einen Reader für XML Bookmark Exchange Language Dateien.
Die DOM Bookmarks Application stellt einen Reader für XML Bookmark Exchange Language (XBEL) Dateien zur Verfügung, der die DOM-basierte XML API von Qt zum Lesen und Parsen der Dateien verwendet. Das QXmlStream Bookmarks Example bietet einen alternativen Weg, um diesen Dateityp zu lesen.
Die XbelTree Klassendefinition
Die Klasse XbelTree verfügt über Funktionen zum Lesen und Schreiben in das Dateisystem. Sie erbt von der Klasse QTreeWidget, enthält das Modell für die Darstellung der Bookmarks und ermöglicht deren Bearbeitung.
class XbelTree : public QTreeWidget { Q_OBJECT public: explicit XbelTree(QWidget *parent = nullptr); bool read(QIODevice *device); bool write(QIODevice *device) const; protected: #if QT_CONFIG(clipboard) && QT_CONFIG(contextmenu) void contextMenuEvent(QContextMenuEvent *event) override; #endif private slots: void updateDomElement(const QTreeWidgetItem *item, int column); private: void parseFolderElement(const QDomElement &element, QTreeWidgetItem *parentItem = nullptr); QTreeWidgetItem *createItem(const QDomElement &element, QTreeWidgetItem *parentItem = nullptr); QDomDocument domDocument; QIcon folderIcon; QIcon bookmarkIcon; };
Die Implementierung der Klasse XbelTree
Der XbelTree
-Konstruktor akzeptiert eine QWidget, in der er platziert wird. folderIcon
ist auf den Modus QIcon::Normal eingestellt, in dem die Pixmap nur angezeigt wird, wenn der Benutzer nicht mit dem Symbol interagiert. Die QStyle::SP_DirClosedIcon, QStyle::SP_DirOpenIcon und QStyle::SP_FileIcon entsprechen Standard-Pixmaps, die dem Stil Ihrer GUI entsprechen.
XbelTree::XbelTree(QWidget *parent) : QTreeWidget(parent) { header()->setSectionResizeMode(QHeaderView::Stretch); setHeaderLabels({tr("Title"), tr("Location")}); folderIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirClosedIcon), QIcon::Normal, QIcon::Off); folderIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirOpenIcon), QIcon::Normal, QIcon::On); bookmarkIcon.addPixmap(style()->standardPixmap(QStyle::SP_FileIcon)); }
Die Funktion read()
öffnet die angegebene Datei QIODevice mit QDomDocument::setContent. Wenn das Öffnen der Datei erfolgreich war und die Kopfzeilen der obersten Ebene überprüft wurden, wird der Inhalt der Klasse gelöscht, bevor der Inhalt der Datei geparst wird, indem alle XML-Knoten der obersten Ebene durchlaufen werden und parseFolderElement()
für jeden von ihnen aufgerufen wird.
bool XbelTree::read(QIODevice *device) { QDomDocument::ParseResult result = domDocument.setContent(device, QDomDocument::ParseOption::UseNamespaceProcessing); if (!result) { QMessageBox::information(window(), tr("DOM Bookmarks"), tr("Parse error at line %1, column %2:\n%3") .arg(result.errorLine) .arg(result.errorColumn) .arg(result.errorMessage)); return false; } QDomElement root = domDocument.documentElement(); if (root.tagName() != "xbel") { QMessageBox::information(window(), tr("DOM Bookmarks"), tr("The file is not an XBEL file.")); return false; } else if (root.hasAttribute(versionAttribute) && root.attribute(versionAttribute) != "1.0"_L1) { QMessageBox::information(window(), tr("DOM Bookmarks"), tr("The file is not an XBEL version 1.0 " "file.")); return false; } clear(); disconnect(this, &QTreeWidget::itemChanged, this, &XbelTree::updateDomElement); QDomElement child = root.firstChildElement(folderElement); while (!child.isNull()) { parseFolderElement(child); child = child.nextSiblingElement(folderElement); } connect(this, &QTreeWidget::itemChanged, this, &XbelTree::updateDomElement); return true; }
Die Funktion parseFolderElement()
behandelt die verschiedenen Elementtypen und ruft sich selbst rekursiv auf, wenn das Element ein Unterordner ist.
void XbelTree::parseFolderElement(const QDomElement &element, QTreeWidgetItem *parentItem) { QTreeWidgetItem *item = createItem(element, parentItem); QString title = element.firstChildElement(titleElement).text(); if (title.isEmpty()) title = tr("Folder"); item->setFlags(item->flags() | Qt::ItemIsEditable); item->setIcon(0, folderIcon); item->setText(0, title); bool folded = (element.attribute(foldedAttribute) != "no"_L1); item->setExpanded(!folded); constexpr char16_t midDot = u'\xB7'; static const QString dots = QString(30, midDot); QDomElement child = element.firstChildElement(); while (!child.isNull()) { if (child.tagName() == folderElement) { parseFolderElement(child, item); } else if (child.tagName() == bookmarkElement) { QTreeWidgetItem *childItem = createItem(child, item); QString title = child.firstChildElement(titleElement).text(); if (title.isEmpty()) title = tr("Folder"); childItem->setFlags(item->flags() | Qt::ItemIsEditable); childItem->setIcon(0, bookmarkIcon); childItem->setText(0, title); childItem->setText(1, child.attribute(hrefAttribute)); } else if (child.tagName() == "separator"_L1) { QTreeWidgetItem *childItem = createItem(child, item); childItem->setFlags(item->flags() & ~(Qt::ItemIsSelectable | Qt::ItemIsEditable)); childItem->setText(0, dots); } child = child.nextSiblingElement(); } }
Die Funktion write()
speichert das domDocument unter Verwendung von QDomDocument::save unter der angegebenen Adresse QIODevice.
bool XbelTree::write(QIODevice *device) const { const int IndentSize = 4; QTextStream out(device); domDocument.save(out, IndentSize); return true; }
Die MainWindow-Klassendefinition
Die Klasse MainWindow
ist eine Unterklasse von QMainWindow, mit einem Menü File
und einem Menü Help
.
class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(); public slots: void open(); void saveAs(); void about(); private: void createMenus(); XbelTree *xbelTree; };
Die Implementierung der MainWindow-Klasse
Der MainWindow
-Konstruktor instanziiert das XbelTree-Objekt und setzt dessen Kopfzeile mit einem QStringList -Objekt, labels
. Der Konstruktor ruft auch createMenus()
auf, um die Menüs einzurichten. Die statusBar()
wird verwendet, um die Meldung "Ready" anzuzeigen.
MainWindow::MainWindow() { xbelTree = new XbelTree; setCentralWidget(xbelTree); createMenus(); statusBar()->showMessage(tr("Ready")); setWindowTitle(tr("DOM Bookmarks")); const QSize availableSize = screen()->availableGeometry().size(); resize(availableSize.width() / 2, availableSize.height() / 3); }
Die Funktion createMenus()
füllt die Menüs auf und setzt die Tastaturkürzel.
void MainWindow::createMenus() { QMenu *fileMenu = menuBar()->addMenu(tr("&File")); QAction *openAct = fileMenu->addAction(tr("&Open..."), this, &MainWindow::open); openAct->setShortcuts(QKeySequence::Open); QAction *saveAsAct = fileMenu->addAction(tr("&Save As..."), this, &MainWindow::saveAs); saveAsAct->setShortcuts(QKeySequence::SaveAs); QAction *exitAct = fileMenu->addAction(tr("E&xit"), this, &QWidget::close); exitAct->setShortcuts(QKeySequence::Quit); menuBar()->addSeparator(); QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addAction(tr("&About"), this, &MainWindow::about); helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); }
Die Funktion open()
ermöglicht es dem Benutzer, eine XBEL-Datei mit QFileDialog zu öffnen. Eine Warnmeldung wird zusammen mit fileName
und errorString
angezeigt, wenn die Datei nicht gelesen werden kann oder ein Parse-Fehler auftritt. Wenn dies gelingt, wird XbelTree::read()
aufgerufen.
void MainWindow::open() { QFileDialog fileDialog(this, tr("Open Bookmark File"), QDir::currentPath()); fileDialog.setMimeTypeFilters({"application/x-xbel"_L1}); if (fileDialog.exec() != QDialog::Accepted) return; const QString fileName = fileDialog.selectedFiles().constFirst(); QFile file(fileName); if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this, tr("DOM Bookmarks"), tr("Cannot read file %1:\n%2.") .arg(QDir::toNativeSeparators(fileName), file.errorString())); return; } if (xbelTree->read(&file)) statusBar()->showMessage(tr("File loaded"), 2000); }
Die Funktion saveAs()
zeigt eine QFileDialog an und fordert den Benutzer auf, eine fileName
einzugeben. Ähnlich wie die Funktion open()
zeigt auch diese Funktion eine Warnmeldung an, wenn die Datei nicht beschrieben werden kann. Wenn dies gelingt, ruft sie XbelTree::write()
auf.
void MainWindow::saveAs() { QFileDialog fileDialog(this, tr("Save Bookmark File"), QDir::currentPath()); fileDialog.setAcceptMode(QFileDialog::AcceptSave); fileDialog.setDefaultSuffix("xbel"_L1); fileDialog.setMimeTypeFilters({"application/x-xbel"_L1}); if (fileDialog.exec() != QDialog::Accepted) return; const QString fileName = fileDialog.selectedFiles().constFirst(); QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("DOM Bookmarks"), tr("Cannot write file %1:\n%2.") .arg(QDir::toNativeSeparators(fileName), file.errorString())); return; } if (xbelTree->write(&file)) statusBar()->showMessage(tr("File saved"), 2000); }
Die Funktion about()
zeigt eine QMessageBox mit einer kurzen Beschreibung des Beispiels an.
void MainWindow::about() { QMessageBox::about(this, tr("About DOM Bookmarks"), tr("The <b>DOM Bookmarks</b> example demonstrates how to " "use Qt's DOM classes to read and write XML " "documents.")); }
Weitere Informationen über XBEL-Dateien finden Sie auf der XML Bookmark Exchange Language Resource Page.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.