End to End GUI Development with Qt5
上QQ阅读APP看书,第一时间看更新

RSS View

Let’s add a new view to our app where we can display some information from a web service using our new classes.

There is nothing new or complicated here, so I won’t show all the code, but there are a few steps to remember:

  1. Create a new RssView.qml view in cm-ui/views and copy the QML from SplashView for now, replacing the "Splash View" text with "Rss View"
  2. Add the view to views.qrc in the /views prefix block and with an alias RssView.qml
  3. Add the goRssView() signal to NavigationController
  1. In MasterView, add the onGoRssView slot to the Connections element and use it to navigate to RssView
  1. In NavigationBar, add a new NavigationButton with iconCharacter uf09e, description RSS Feed, and hoverColour as #8acece, and use the onNavigationButtonClicked slot to call goRssView() on the NavigationController

With just a few simple steps, we’ve now got a brand new view wired up that we can access using the navigation bar:

Next, we’ll add a context command bar to the view with the following steps:

  1. In CommandController, add a new private member list rssViewContextCommands
  2. Add an accessor method ui_rssViewContextCommands()
  1. Add a Q_PROPERTY named ui_rssViewContextCommands
  2. Add a new slot onRssRefreshExecuted() that simply writes a debug message to the console; for now to indicate it has been called
  3. Append a new command called rssRefreshCommand to rssViewContextCommands with the 0xf021 icon character and “Refresh” label and connect it to the onRssRefreshExecuted() slot
  4. In RssView, add a CommandBar component with the commandList wired up to ui_rssViewContextCommands on the command controller

All the hard work from earlier chapters is really paying dividends now; our new view has got its own command bar and a fully functional refresh button. When you click on it, it should write out the debug message you added to the console:

Next, we need to create instances of our NetworkAccessManager and WebRequest classes. As usual, we will add these to MasterController and inject a dependency to CommandController.

In MasterController, add two new private members:

NetworkAccessManager* networkAccessManager{nullptr};
WebRequest* rssWebRequest{nullptr};

Remember to include the relevant headers. Instantiate these new members in the Implementation constructor, ensuring that they are created before commandController:

networkAccessManager = new NetworkAccessManager(masterController);
rssWebRequest = new WebRequest(masterController, networkAccessManager, QUrl("http://feeds.bbci.co.uk/news/rss.xml?edition=uk"));

Here we are using the URL for a BBC RSS feed relevant to the UK; feel free to swap this for another feed of your choice simply by replacing the hyperlink text.

Next, pass rssWebRequest as a new parameter to the commandController constructor:

commandController = new CommandController(masterController, databaseController, navigationController, newClient, clientSearch, rssWebRequest);

Next, edit CommandController to take this new parameter as a pointer to the interface:

explicit CommandController(QObject* _parent = nullptr, IDatabaseController* databaseController = nullptr, NavigationController* navigationController = nullptr, models::Client* newClient = nullptr, models::ClientSearch* clientSearch = nullptr, networking::IWebRequest* rssWebRequest = nullptr);

Pass this pointer through the Implementation constructor and store it in a private member variable as we do for all the other dependencies:

IWebRequest* rssWebRequest{nullptr};

We can now update the onRssRefreshExecuted() slot to execute the web request:

void CommandController::onRssRefreshExecuted()
{
    qDebug() << "You executed the Rss Refresh command!";

implementation->rssWebRequest->execute(); }

The command controller now reacts to the user pressing the refresh button and executes the web request. However, we don’t currently do anything when we receive the response. Let’s add a delegate to MasterController in the public slots section:

void MasterController::onRssReplyReceived(int statusCode, QByteArray body)
{
    qDebug() << "Received RSS request response code " << statusCode << ":";
    qDebug() << body;
}

Now, after we instantiate rssWebRequest in Implementation, we can wire up the requestComplete signal to our new delegate:

QObject::connect(rssWebRequest, &WebRequest::requestComplete, masterController, &MasterController::onRssReplyReceived);

Now build and run the application, navigate to the RSS View, and click on Refresh. After a brief delay, while the request is executed, you will see all sorts of nonsense printed to the Application Output console:

Received RSS request response code 200 :
"<?xml version="1.0" encoding="UTF-8"?>n<?xml-stylesheet title=...”

Congratulations! You’ve got an RSS feed! Now, what is it?