Home > Articles > Programming > C/C++

  • Print
  • + Share This
This chapter is from the book

Using a Web Browser to Provide Online Help

Large applications may require more online help than tooltips, status tips, and "What's This?" help can reasonably show. A simple solution to this is to provide the help text in HTML format and launch the user's web browser at the appropriate page.

Applications that include a help browser typically have a Help entry in the main window's Help menu and a Help button in every dialog. In this section, we will show how to use the QDesktopServices class to provide the functionality for these buttons.

The application's main window will typically have a help() slot that is called when the user presses F1 or clicks the Help|Help menu option.

void MainWindow::help()
{
    QUrl url(directoryOf("doc").absoluteFilePath("index.html"));
    url.setScheme("file");
    QDesktopServices::openUrl(url);
}

In this example, we assume that our application's HTML help files are in a subdirectory called doc. The QDir::absoluteFilePath() function returns a QString with the full path to the given file name. We begin by creating a QUrl object with the path to the help file. Since this is help for the main window, we use our help system's index.html file from which all the other help files are accessible through hyperlinks. Next, we set the URL's scheme to "file" so that the file we have set will be looked for in the local file system. Finally, we use the desktop services' openUrl() static convenience function to launch the user's web browser.

We do not know which web browser will be used, so we must be careful to make our HTML valid and compatible with the browsers that our users might be using. Most web browsers will set their local working directory to the URL's path, and will therefore assume that any images and hyperlinks that do not have absolute paths have the working directory as their root. All this means is that we must put all our HTML files and image files in our doc directory (or subdirectories under it) and make all our references relative, except for links to external web sites.

QDir MainWindow::directoryOf(const QString &subdir)
{
    QDir dir(QApplication::applicationDirPath());

#if defined(Q_OS_WIN)
    if (dir.dirName().toLower() == "debug"
            || dir.dirName().toLower() == "release")
        dir.cdUp();
#elif defined(Q_OS_MAC)
    if (dir.dirName() == "MacOS") {
        dir.cdUp();
        dir.cdUp();
        dir.cdUp();
    }
#endif
    dir.cd(subdir);
    return dir;
}

The static directoryOf() function returns a QDir corresponding to the specified subdirectory relative to the application's directory. On Windows, the application's executable usually lives in a debug or release subdirectory, in which case we move one directory up; on Mac OS X, we take the bundle directory structure into account.

For dialogs, we will normally want to launch the web browser at a specific page from within our help system's pages, and perhaps at a specific point within the page. For example:

void EntryDialog::help()
{
    QUrl url(directoryOf("doc").absoluteFilePath("forms.html"));
    url.setScheme("file");
    url.setFragment("editing");
    QDesktopServices::openUrl(url);
}

This slot is called from inside a dialog when the user clicks the dialog's Help button. It is very similar to the previous example, except that we have chosen a different starting page. This particular page has help text for several different forms, with anchor references (e.g., <a name="editing">) in the HTML to indicate where each form's help text begins. To access a particular place within a page, we call setFragment() and pass the anchor we want the page scrolled to.

Providing help files in HTML format and making them available to users via their own web browser is simple and convenient. But web browsers cannot access the application's resources (such as icons), and they cannot easily be customized to suit the application. Also, if we jump to a particular page as we did for the EntryDialog, clicking the browser's Home or Back button will not have the desired effect.

  • + Share This
  • 🔖 Save To Your Account