Viadeo Twitter Google Bookmarks ! Facebook Digg MySpace Yahoo MyWeb Blinklist Netvouz Reddit Simpy StumbleUpon Bookmarks Windows Live Favorites 
Logo Documentation Qt ·  Page d'accueil  ·  Toutes les classes  ·  Toutes les fonctions  ·  Vues d'ensemble  · 

License Wizard Example



The License Wizard example shows how to implement complex wizards in Qt.

Screenshot of the License Wizard example

Most wizards have a linear structure, with page 1 followed by page 2 and so on until the last page. The Class Wizard example shows how to create such wizards.

Some wizards are more complex in that they allow different traversal paths based on the information provided by the user. The License Wizard example illustrates this. It provides five wizard pages; depending on which options are selected, the user can reach different pages.

The License Wizard pages

The example consists of the following classes:

  • LicenseWizard inherits QWizard and implements a non-linear five-page wizard that leads the user through the process of choosing a license agreement.
  • IntroPage, EvaluatePage, RegisterPage, DetailsPage, and ConclusionPage are QWizardPage subclasses that implement the wizard pages.

The LicenseWizard Class

The LicenseWizard class derives from QWizard and provides a five-page wizard that guides the user through the process of registering their copy of a fictitious software product. Here's the class definition:

 class LicenseWizard : public QWizard

     enum { Page_Intro, Page_Evaluate, Page_Register, Page_Details,
            Page_Conclusion };

     LicenseWizard(QWidget *parent = 0);

 private slots:
     void showHelp();

The class's public API is limited to a constructor and an enum. The enum defines the IDs associated with the various pages:

Class nameEnum valuePage ID

For this example, the IDs are arbitrary. The only constraints are that they must be unique and different from -1. IDs allow us to refer to pages.

 LicenseWizard::LicenseWizard(QWidget *parent)
     : QWizard(parent)
     setPage(Page_Intro, new IntroPage);
     setPage(Page_Evaluate, new EvaluatePage);
     setPage(Page_Register, new RegisterPage);
     setPage(Page_Details, new DetailsPage);
     setPage(Page_Conclusion, new ConclusionPage);


In the constructor, we create the five pages, insert them into the wizard using QWizard::setPage(), and set Page_Intro to be the first page.

 #ifndef Q_WS_MAC

We set the style to ModernStyle on all platforms except Mac OS X,

     setOption(HaveHelpButton, true);
     setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo.png"));

     connect(this, SIGNAL(helpRequested()), this, SLOT(showHelp()));

     setWindowTitle(tr("License Wizard"));

We configure the QWizard to show a Help button, which is connected to our showHelp() slot. We also set the LogoPixmap for all pages that have a header (i.e., EvaluatePage, RegisterPage, and DetailsPage).

 void LicenseWizard::showHelp()
     static QString lastHelpMessage;

     QString message;

     switch (currentId()) {
     case Page_Intro:
         message = tr("The decision you make here will affect which page you "
                      "get to see next.");
         message = tr("This help is likely not to be of any help.");

     if (lastHelpMessage == message)
         message = tr("Sorry, I already gave what help I could. "
                      "Maybe you should try asking a human?");

     QMessageBox::information(this, tr("License Wizard Help"), message);

     lastHelpMessage = message;

In showHelp(), we display help texts that are appropiate for the current page. If the user clicks Help twice for the same page, we say, "Sorry, I already gave what help I could. Maybe you should try asking a human?"

The IntroPage Class

The pages are defined in licensewizard.h and implemented in licensewizard.cpp, together with LicenseWizard.

Here's the definition and implementation of IntroPage:

 class IntroPage : public QWizardPage

     IntroPage(QWidget *parent = 0);

     int nextId() const;

     QLabel *topLabel;
     QRadioButton *registerRadioButton;
     QRadioButton *evaluateRadioButton;

 IntroPage::IntroPage(QWidget *parent)
     : QWizardPage(parent)
     setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/watermark.png"));

     topLabel = new QLabel(tr("This wizard will help you register your copy of "
                              "<i>Super Product One</i>&trade; or start "
                              "evaluating the product."));

     registerRadioButton = new QRadioButton(tr("&Register your copy"));
     evaluateRadioButton = new QRadioButton(tr("&Evaluate the product for 30 "

     QVBoxLayout *layout = new QVBoxLayout;

A page inherits from QWizardPage. We set a title and a watermark pixmap. By not setting any subTitle, we ensure that no header is displayed for this page. (On Windows, it is customary for wizards to display a watermark pixmap on the first and last pages, and to have a header on the other pages.)

 int IntroPage::nextId() const
     if (evaluateRadioButton->isChecked()) {
         return LicenseWizard::Page_Evaluate;
     } else {
         return LicenseWizard::Page_Register;

The nextId() function returns the ID for EvaluatePage if the Evaluate the product for 30 days option is checked; otherwise it returns the ID for RegisterPage.

The EvaluatePage Class

The EvaluatePage is slightly more involved:

 class EvaluatePage : public QWizardPage

     EvaluatePage(QWidget *parent = 0);

     int nextId() const;

     QLabel *nameLabel;
     QLabel *emailLabel;
     QLineEdit *nameLineEdit;
     QLineEdit *emailLineEdit;

 EvaluatePage::EvaluatePage(QWidget *parent)
     : QWizardPage(parent)
     setTitle(tr("Evaluate <i>Super Product One</i>&trade;"));
     setSubTitle(tr("Please fill both fields. Make sure to provide a valid "
                    "email address (e.g.,"));

     nameLabel = new QLabel(tr("N&ame:"));
     nameLineEdit = new QLineEdit;
     registerField("*", nameLineEdit);
     registerField("*", emailLineEdit);

First, we set the page's title and subTitle.

Then we create the child widgets, create wizard fields associated with them, and put them into layouts. The fields are created with an asterisk (*) next to their name. This makes them mandatory fields, that is, fields that must be filled before the user can press the Next button (Continue on Mac OS X). The fields' values can be accessed from any other page using QWizardPage::field().

Resetting the page amounts to clearing the two text fields.

 int EvaluatePage::nextId() const
     return LicenseWizard::Page_Conclusion;

The next page is always the ConclusionPage.

The ConclusionPage Class

The RegisterPage and DetailsPage are very similar to EvaluatePage. Let's go directly to the ConclusionPage:

 class ConclusionPage : public QWizardPage

     ConclusionPage(QWidget *parent = 0);

     void initializePage();
     int nextId() const;
     void setVisible(bool visible);

 private slots:
     void printButtonClicked();

     QLabel *bottomLabel;
     QCheckBox *agreeCheckBox;

This time, we reimplement QWizardPage::initializePage() and QWidget::setVisible(), in addition to nextId(). We also declare a private slot: printButtonClicked().

 int IntroPage::nextId() const
     if (evaluateRadioButton->isChecked()) {
         return LicenseWizard::Page_Evaluate;
     } else {
         return LicenseWizard::Page_Register;

The default implementation of QWizardPage::nextId() returns the page with the next ID, or -1 if the current page has the highest ID. This behavior would work here, because Page_Conclusion equals 5 and there is no page with a higher ID, but to avoid relying on such subtle behavior, we reimplement nextId() to return -1.

 void ConclusionPage::initializePage()
     QString licenseText;

     if (wizard()->hasVisitedPage(LicenseWizard::Page_Evaluate)) {
         licenseText = tr("<u>Evaluation License Agreement:</u> "
                          "You can use this software for 30 days and make one "
                          "backup, but you are not allowed to distribute it.");
     } else if (wizard()->hasVisitedPage(LicenseWizard::Page_Details)) {
         licenseText = tr("<u>First-Time License Agreement:</u> "
                          "You can use this software subject to the license "
                          "you will receive by email.");
     } else {
         licenseText = tr("<u>Upgrade License Agreement:</u> "
                          "This software is licensed under the terms of your "
                          "current license.");

We use QWizard::hasVisitedPage() to determine the type of license agreement the user has chosen. If the user filled the EvaluatePage, the license text refers to an Evaluation License Agreement. If the user filled the DetailsPage, the license text is a First-Time License Agreement. If the user provided an upgrade key and skipped the DetailsPage, the license text is an Update License Agreement.

 void ConclusionPage::setVisible(bool visible)

     if (visible) {
         wizard()->setButtonText(QWizard::CustomButton1, tr("&Print"));
         wizard()->setOption(QWizard::HaveCustomButton1, true);
         connect(wizard(), SIGNAL(customButtonClicked(int)),
                 this, SLOT(printButtonClicked()));
     } else {
         wizard()->setOption(QWizard::HaveCustomButton1, false);
         disconnect(wizard(), SIGNAL(customButtonClicked(int)),
                    this, SLOT(printButtonClicked()));

We want to display a Print button in the wizard when the ConclusionPage is up. One way to accomplish this is to reimplement QWidget::setVisible():

See also QWizard, Class Wizard Example, and Trivial Wizard Example.


Best Of

Actualités les plus lues

  1. Microsoft ouvre aux autres compilateurs C++ AMP, la spécification pour la conception d'applications parallèles C++ utilisant le GPU 22
  2. « Quelque chose ne va vraiment pas avec les développeurs "modernes" », un développeur à "l'ancienne" critique la multiplication des bibliothèques 27
  3. Les développeurs ignorent-ils trop les failles découvertes dans leur code ? Prenez-vous en compte les remarques des autres ? 17
  4. RIM : « 13 % des développeurs ont gagné plus de 100 000 $ sur l'AppWord », Qt et open-source au menu du BlackBerry DevCon Europe 0
  5. BlackBerry 10 : premières images du prochain OS de RIM qui devrait intégrer des widgets et des tuiles inspirées de Windows Phone 0
  6. Adieu qmake, bienvenue qbs : Qt Building Suite, un outil déclaratif et extensible pour la compilation de projets Qt 17
  7. Quelles nouveautés de C++11 Visual C++ doit-il rapidement intégrer ? Donnez-nous votre avis 10
Page suivante

Le blog Digia au hasard


Déploiement d'applications Qt Commercial sur les tablettes Windows 8

Le blog Digia est l'endroit privilégié pour la communication sur l'édition commerciale de Qt, où des réponses publiques sont apportées aux questions les plus posées au support. Lire l'article.



Liens utiles


  • Vous souhaitez rejoindre la rédaction ou proposer un tutoriel, une traduction, une question... ? Postez dans le forum Contribuez ou contactez-nous par MP ou par email (voir en bas de page).

Qt dans le magazine

Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. Qt 4.6
Copyright © 2012 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP !

Hébergement Web