Application DOM Bookmarks
Fournit un lecteur pour les fichiers XML Bookmark Exchange Language.
L'application DOM Bookmarks fournit un lecteur pour les fichiers XML Bookmark Exchange Language (XBEL) qui utilise l'API XML de Qt basée sur DOM pour lire et analyser les fichiers. L'exemple de signets QXmlStream fournit une autre façon de lire ce type de fichier.

Définition de la classe XbelTree
La classe XbelTree possède des fonctions de lecture et d'écriture dans le système de fichiers. Elle hérite de la classe QTreeWidget, contient le modèle d'affichage des signets et permet de l'éditer.
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; };
Mise en œuvre de la classe XbelTree
Le constructeur de XbelTree accepte un QWidget dans lequel il est placé. Le site folderIcon est configuré en mode QIcon::Normal, dans lequel la pixmap n'est affichée que lorsque l'utilisateur n'interagit pas avec l'icône. Les QStyle::SP_DirClosedIcon, QStyle::SP_DirOpenIcon, et QStyle::SP_FileIcon correspondent à des pixmaps standards qui suivent le style de votre interface graphique.
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)); }
La fonction read() ouvre le fichier QIODevice à l'aide de QDomDocument::setContent. Si elle réussit à ouvrir le fichier et que les en-têtes de premier niveau sont vérifiés, le contenu de la classe est effacé avant que le contenu du fichier ne soit analysé en parcourant tous les nœuds XML de premier niveau et en appelant parseFolderElement() sur chacun d'entre eux.
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; }
La fonction parseFolderElement() gère les différents types d'éléments et s'appelle elle-même de manière récursive si l'élément est un sous-dossier.
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(); } }
La fonction write() enregistre le domDocument dans le dossier QIODevice à l'aide de QDomDocument::save.
bool XbelTree::write(QIODevice *device) const { const int IndentSize = 4; QTextStream out(device); domDocument.save(out, IndentSize); return true; }
Définition de la classe MainWindow
La classe MainWindow est une sous-classe de QMainWindow, avec un menu File et un menu Help.
class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(); public slots: void open(); void saveAs(); void about(); private: void createMenus(); XbelTree *xbelTree; };
Implémentation de la classe MainWindow
Le constructeur de MainWindow instancie l'objet membre XbelTree et définit son en-tête avec un objet QStringList, labels. Le constructeur invoque également createMenus() pour configurer les menus. La fonction statusBar() est utilisée pour afficher le message "Ready".
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); }
La fonction createMenus() remplit les menus et définit les raccourcis clavier.
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); }
La fonction open() permet à l'utilisateur d'ouvrir un fichier XBEL à l'aide de QFileDialog. Un message d'avertissement est affiché avec les messages fileName et errorString si le fichier ne peut pas être lu ou s'il y a une erreur d'analyse. En cas de succès, la fonction appelle XbelTree::read().
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); }
La fonction saveAs() affiche un message QFileDialog, invitant l'utilisateur à saisir un message fileName. Comme la fonction open(), cette fonction affiche également un message d'avertissement s'il est impossible d'écrire dans le fichier. En cas de succès, elle appelle XbelTree::write().
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); }
La fonction about() affiche une page QMessageBox avec une brève description de l'exemple.
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.")); }
Voir la page de ressources du langage d'échange de signets XML pour plus d'informations sur les fichiers XBEL.
© 2026 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.