summaryrefslogtreecommitdiffstats
path: root/examples/corelib/serialization
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2023-06-07 15:32:28 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2023-06-14 11:57:31 +0200
commite54a7c56677280d9a9eb976dd455085dcce10c40 (patch)
tree63ac9abc55e98edf9f8ea9c6bc674b57f965cb54 /examples/corelib/serialization
parent4b6986db32eef511718e9010636c5485b6512ac9 (diff)
Move RSS listing example to networking
It's really showing how to request a resource and act on its becoming available. The use of XML to do so is incidental; the use of networking is central. Pick-to: 6.6 6.5 Task-number: QTBUG-111228 Change-Id: Ibcf438c7ef3b2464ddfa8b96a79fb15523e4a468 Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'examples/corelib/serialization')
-rw-r--r--examples/corelib/serialization/CMakeLists.txt3
-rw-r--r--examples/corelib/serialization/rsslisting/CMakeLists.txt38
-rw-r--r--examples/corelib/serialization/rsslisting/doc/images/rsslisting.pngbin19739 -> 0 bytes
-rw-r--r--examples/corelib/serialization/rsslisting/doc/src/rsslisting.qdoc129
-rw-r--r--examples/corelib/serialization/rsslisting/main.cpp16
-rw-r--r--examples/corelib/serialization/rsslisting/rsslisting.cpp126
-rw-r--r--examples/corelib/serialization/rsslisting/rsslisting.h54
-rw-r--r--examples/corelib/serialization/rsslisting/rsslisting.pro8
-rw-r--r--examples/corelib/serialization/serialization.pro2
9 files changed, 0 insertions, 376 deletions
diff --git a/examples/corelib/serialization/CMakeLists.txt b/examples/corelib/serialization/CMakeLists.txt
index 7dd5d476d1..ad14a179b1 100644
--- a/examples/corelib/serialization/CMakeLists.txt
+++ b/examples/corelib/serialization/CMakeLists.txt
@@ -4,9 +4,6 @@
qt_internal_add_example(cbordump)
qt_internal_add_example(convert)
qt_internal_add_example(savegame)
-if(TARGET Qt6::Network AND TARGET Qt6::Widgets)
- qt_internal_add_example(rsslisting)
-endif()
if(TARGET Qt6::Widgets)
qt_internal_add_example(streambookmarks)
endif()
diff --git a/examples/corelib/serialization/rsslisting/CMakeLists.txt b/examples/corelib/serialization/rsslisting/CMakeLists.txt
deleted file mode 100644
index 405a01ce56..0000000000
--- a/examples/corelib/serialization/rsslisting/CMakeLists.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
-
-cmake_minimum_required(VERSION 3.16)
-project(rsslisting LANGUAGES CXX)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/serialization/rsslisting")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
-
-qt_standard_project_setup()
-
-qt_add_executable(rsslisting
- main.cpp
- rsslisting.cpp rsslisting.h
-)
-
-set_target_properties(rsslisting PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(rsslisting PRIVATE
- Qt6::Core
- Qt6::Gui
- Qt6::Network
- Qt6::Widgets
-)
-
-install(TARGETS rsslisting
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/corelib/serialization/rsslisting/doc/images/rsslisting.png b/examples/corelib/serialization/rsslisting/doc/images/rsslisting.png
deleted file mode 100644
index 0b05375f93..0000000000
--- a/examples/corelib/serialization/rsslisting/doc/images/rsslisting.png
+++ /dev/null
Binary files differ
diff --git a/examples/corelib/serialization/rsslisting/doc/src/rsslisting.qdoc b/examples/corelib/serialization/rsslisting/doc/src/rsslisting.qdoc
deleted file mode 100644
index 260d26811c..0000000000
--- a/examples/corelib/serialization/rsslisting/doc/src/rsslisting.qdoc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example serialization/rsslisting
- \examplecategory {Networking}
- \meta tag {serialization}
- \title A minimal RSS listing application
-
- \brief A demonstration of how to fetch and display a network resource.
-
- This example shows how to fetch a resource the user has requested and
- display data contained in the response, illustrated by an RSS listing
- application. (RDF Site Summary, or Really Simple Syndication, is a standard
- format for communicating updates to web sites. See
- https://www.rssboard.org/rss-specification for details.) The user inferface
- in the illustration is simple, as the focus of this example is on how to use
- networking, but naturally a more sophisticated interface would be wanted for
- a serious RSS reader.
-
- The example also illustrates how to do asynchronous parsing of data as it is
- received, preserving state in member variables so that an incremental parser
- can consume chunks of data as they arrive over the network. Constituents of
- the parsed content may start in one chunk of data but not be completed until
- a later chunk, requiring the parser to retain state between calls.
-
- \image rsslisting.png
-
- The main program is fairly minimal. It simply instantiates a \l QApplication
- and the \c RSSListing widget, shows the latter and hands over control to the
- former. For the sake of illustration, it gives the widget the Qt blog's URL
- as default value for the resource to check.
-
- \snippet serialization/rsslisting/main.cpp 0
-
- \section1 The RSSListing class
-
- \snippet serialization/rsslisting/rsslisting.h 0
-
- The widget itself provides a simple user interface for specifying the URL to
- fetch and, once available updates are displayed, controlling the downloading
- of updated items. A \l QLineEdit provides for input of the URL, and a
- \l QTreeWidget for display of the results once fetched.
-
- The widget downloads and parses the RSS (a form of XML) asynchronously,
- feeding the data to an XML reader as it arrives. This supports reading of
- very large data sources. Because the data is streamed from the network
- through the XML reader, there is no need to retain the full text of the XML
- in memory. In other context, a similar approach can allow the user to
- interrupt such incremental loading.
-
- \section2 Construction
-
- \snippet serialization/rsslisting/rsslisting.cpp setup
-
- The constructor sets up the assorted components of the widget and connects
- their various signals to the slots it shall use to handle them.
-
- The user interface consists of a line edit, a push button, and a list view
- widget. The line edit is used for entering the URL to fetch; the push button
- starts the process of fetching updates. The line edit is empty by default,
- but the constructor's caller can override that, as our \c main() has done.
- In any case, the user can replace the default with the URL of another RSS
- feed.
-
- The list view shows the updated items reported in the RSS feed.
- Double-clicking on one of these sends its URL to the user's browser or other
- user agent using \l QDesktopServices::openUrl().
-
- \section2 The slots
-
- \snippet serialization/rsslisting/rsslisting.cpp slots
-
- All slots are kept simple by delegating any hard work to private methods.
-
- When the user completes input of a URL, either by clicking the "Fetch"
- button or by pressing the return key in the line edit, the \c fetch() slot
- disables the "Fetch" button and disables further editing of the line edit.
- It clears the display of available updates and delegates to \c get() the
- initiating of an HTTP GET request.
-
- When data is received, the network reply triggers its \l {QNetworkReply::}
- {readyRead()} signal, which \c get() connects to the \c consumeData()
- slot. This checks the response got a successful status code and, if it did,
- calls \c parseXml() to consume the data.
-
- If the network reply gets an error, this is delivered to the \c error()
- slot, which reports the error, clears the XML stream reader then disconnects
- from the reply and deletes it.
-
- On completion (whether successful or otherwise) of a network reply, the \c
- finished() slot restores the UI to be ready to accept a new URL to fetch by
- re-enabling the line edit and "Fetch" button.
-
- \section2 The get() method
-
- \snippet serialization/rsslisting/rsslisting.cpp get
-
- The private \c get() method is used by the \c fetch() slot to initiate an
- HTTP GET request. It first clears the XML stream reader and, if a reply is
- currently active, disconnects and deletes it. If the URL it has been passed
- is valid, it asks the network access manager to GET it. It connects its
- relevant slots to signals of the resulting reply (if any) and sets up its
- XML stream reader to read data from the reply - a network reply object is
- also a \c QIODevice, from which data can be read.
-
- \section2 The parseXml() method
-
- \snippet serialization/rsslisting/rsslisting.cpp parse
-
- When data is received, and thus made available to the XML stream reader, \c
- parseXml() reads from the XML stream, checking for \c item elements and,
- within them, \c title and \c link elements. It will use the \c{rss:about}
- attribute of an \c item as URL in the Link column of the tree-view, failing
- that the content of its \c link element; and it uses the content of the \c
- title element in the Title column of the tree-view. As each \c item element
- closes, its details are turned into a new row in the tree widget, with the
- extracted title and URL in the Title and Link columns.
-
- The variables that keep track of the parsing state - \c linkString, \c
- titleString and \c currentTag - are member variables of the \c RSSListing
- class, even though they are only accessed from this method, because this
- method may be called repeatedly, as new data arrives, and one chunk of
- received data may start an element that isn't completed until a later chunk
- arrives. This enables the parser to operate asynchronously as the data
- arrives, instead of having to wait until all the data has arrived.
-
- \sa QNetworkReply, QXmlStreamReader
-*/
diff --git a/examples/corelib/serialization/rsslisting/main.cpp b/examples/corelib/serialization/rsslisting/main.cpp
deleted file mode 100644
index 7a64db8a0c..0000000000
--- a/examples/corelib/serialization/rsslisting/main.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "rsslisting.h"
-#include <QtWidgets>
-using namespace Qt::StringLiterals;
-
-//! [0]
-int main(int argc, char **argv)
-{
- QApplication app(argc, argv);
- RSSListing rsslisting(u"https://www.qt.io/blog/rss.xml"_s);
- rsslisting.show();
- return app.exec();
-}
-//! [0]
diff --git a/examples/corelib/serialization/rsslisting/rsslisting.cpp b/examples/corelib/serialization/rsslisting/rsslisting.cpp
deleted file mode 100644
index ed7c163c76..0000000000
--- a/examples/corelib/serialization/rsslisting/rsslisting.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "rsslisting.h"
-
-#include <QtCore>
-#include <QtWidgets>
-#include <QtNetwork>
-
-//! [setup]
-RSSListing::RSSListing(const QString &url, QWidget *parent)
- : QWidget(parent), currentReply(0)
-{
- connect(&manager, &QNetworkAccessManager::finished, this, &RSSListing::finished);
-
- lineEdit = new QLineEdit(this);
- lineEdit->setText(url);
- connect(lineEdit, &QLineEdit::returnPressed, this, &RSSListing::fetch);
-
- fetchButton = new QPushButton(tr("Fetch"), this);
- connect(fetchButton, &QPushButton::clicked, this, &RSSListing::fetch);
-
- treeWidget = new QTreeWidget(this);
- connect(treeWidget, &QTreeWidget::itemActivated,
- // Open the link in the browser:
- this, [](QTreeWidgetItem *item) { QDesktopServices::openUrl(QUrl(item->text(1))); });
- treeWidget->setHeaderLabels(QStringList { tr("Title"), tr("Link") });
- treeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
-
- QHBoxLayout *hboxLayout = new QHBoxLayout;
- hboxLayout->addWidget(lineEdit);
- hboxLayout->addWidget(fetchButton);
-
- QVBoxLayout *layout = new QVBoxLayout(this);
- layout->addLayout(hboxLayout);
- layout->addWidget(treeWidget);
-
- setWindowTitle(tr("RSS listing example"));
- resize(640, 480);
-}
-//! [setup]
-
-//! [slots]
-void RSSListing::fetch()
-{
- lineEdit->setReadOnly(true);
- fetchButton->setEnabled(false);
- treeWidget->clear();
-
- get(QUrl(lineEdit->text()));
-}
-
-void RSSListing::consumeData()
-{
- int statusCode = currentReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- if (statusCode >= 200 && statusCode < 300)
- parseXml();
-}
-
-void RSSListing::error(QNetworkReply::NetworkError)
-{
- qWarning("error retrieving RSS feed");
- xml.clear();
- currentReply->disconnect(this);
- currentReply->deleteLater();
- currentReply = nullptr;
-}
-
-void RSSListing::finished(QNetworkReply *reply)
-{
- Q_UNUSED(reply);
- lineEdit->setReadOnly(false);
- fetchButton->setEnabled(true);
-}
-//! [slots]
-
-// Private methods
-
-//! [get]
-void RSSListing::get(const QUrl &url)
-{
- if (currentReply) {
- currentReply->disconnect(this);
- currentReply->deleteLater();
- }
- currentReply = url.isValid() ? manager.get(QNetworkRequest(url)) : nullptr;
- if (currentReply) {
- connect(currentReply, &QNetworkReply::readyRead, this, &RSSListing::consumeData);
- connect(currentReply, &QNetworkReply::errorOccurred, this, &RSSListing::error);
-
- }
- xml.setDevice(currentReply); // Equivalent to clear() if currentReply is null.
-}
-//! [get]
-
-// TODO: this is a candidate for showing how to use coroutines, once available.
-//! [parse]
-void RSSListing::parseXml()
-{
- while (!xml.atEnd()) {
- xml.readNext();
- if (xml.isStartElement()) {
- if (xml.name() == u"item") {
- linkString = xml.attributes().value("rss:about").toString();
- titleString.clear();
- }
- currentTag = xml.name().toString();
- } else if (xml.isEndElement()) {
- if (xml.name() == u"item") {
-
- QTreeWidgetItem *item = new QTreeWidgetItem;
- item->setText(0, titleString);
- item->setText(1, linkString);
- treeWidget->addTopLevelItem(item);
- }
- } else if (xml.isCharacters() && !xml.isWhitespace()) {
- if (currentTag == "title")
- titleString += xml.text();
- else if (currentTag == "link")
- linkString += xml.text();
- }
- }
- if (xml.error() && xml.error() != QXmlStreamReader::PrematureEndOfDocumentError)
- qWarning() << "XML ERROR:" << xml.lineNumber() << ": " << xml.errorString();
-}
-//! [parse]
diff --git a/examples/corelib/serialization/rsslisting/rsslisting.h b/examples/corelib/serialization/rsslisting/rsslisting.h
deleted file mode 100644
index 499bc5d1d4..0000000000
--- a/examples/corelib/serialization/rsslisting/rsslisting.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef RSSLISTING_H
-#define RSSLISTING_H
-
-#include <QNetworkAccessManager>
-#include <QNetworkReply>
-#include <QWidget>
-#include <QXmlStreamReader>
-
-QT_BEGIN_NAMESPACE
-class QLineEdit;
-class QPushButton;
-class QTreeWidget;
-class QTreeWidgetItem;
-class QUrl;
-QT_END_NAMESPACE
-
-//! [0]
-class RSSListing : public QWidget
-{
- Q_OBJECT
-public:
- explicit RSSListing(const QString &url = QString(), QWidget *widget = nullptr);
-
-public slots:
- void fetch();
- void finished(QNetworkReply *reply);
- void consumeData();
- void error(QNetworkReply::NetworkError);
-
-private:
- void parseXml();
- void get(const QUrl &url);
-
- // Parser state:
- QXmlStreamReader xml;
- QString currentTag;
- QString linkString;
- QString titleString;
-
- // Network state:
- QNetworkAccessManager manager;
- QNetworkReply *currentReply;
-
- // UI elements:
- QLineEdit *lineEdit;
- QTreeWidget *treeWidget;
- QPushButton *fetchButton;
-};
-//! [0]
-
-#endif
diff --git a/examples/corelib/serialization/rsslisting/rsslisting.pro b/examples/corelib/serialization/rsslisting/rsslisting.pro
deleted file mode 100644
index 7619755b8f..0000000000
--- a/examples/corelib/serialization/rsslisting/rsslisting.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-HEADERS += rsslisting.h
-SOURCES += main.cpp rsslisting.cpp
-QT += network widgets
-requires(qtConfig(treewidget))
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/corelib/serialization/rsslisting
-INSTALLS += target
diff --git a/examples/corelib/serialization/serialization.pro b/examples/corelib/serialization/serialization.pro
index 9f0ced0282..e20fcb57fd 100644
--- a/examples/corelib/serialization/serialization.pro
+++ b/examples/corelib/serialization/serialization.pro
@@ -6,6 +6,4 @@ SUBDIRS = \
qtHaveModule(widgets) {
SUBDIRS += streambookmarks
- qtHaveModule(network): SUBDIRS += \
- rsslisting
}