Viadeo Twitter Google Bookmarks ! Facebook Digg del.icio.us 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  · 

Class Wizard Example

Files:

Images:

The License Wizard example shows how to implement linear wizards using QWizard.

Screenshot of the Class Wizard example

Most wizards have a linear structure, with page 1 followed by page 2 and so on until the last page. Some wizards are more complex in that they allow different traversal paths based on the information provided by the user. The License Wizard example shows how to create such wizards.

The Class Wizard example consists of the following classes:

  • ClassWizard inherits QWizard and provides a three-step wizard that generates the skeleton of a C++ class based on the user's input.
  • IntroPage, ClassInfoPage, CodeStylePage, OutputFilesPage, and ConclusionPage are QWizardPage subclasses that implement the wizard pages.

ClassWizard Class Definition

The Class Wizard pages

We will see how to subclass QWizard to implement our own wizard. The concrete wizard class is called ClassWizard and provides five pages:

  • The first page is an introduction page, telling the user what the wizard is going to do.
  • The second page asks for a class name and a base class, and allows the user to specify whether the class should have a Q_OBJECT macro and what constructors it should provide.
  • The third page allows the user to set some options related to the code style, such as the macro used to protect the header file from multiple inclusion (e.g., MYDIALOG_H).
  • The fourth page allows the user to specify the names of the output files.
  • The fifth page is a conclusion page.

Although the program is just an example, if you press Finish (Done on Mac OS X), actual C++ source files will actually be generated.

The ClassWizard Class

Here's the ClassWizard definition:

 class ClassWizard : public QWizard
 {
     Q_OBJECT

 public:
     ClassWizard(QWidget *parent = 0);

     void accept();
 };

The class reimplements QDialog's accept() slot. This slot is called when the user clicks Finish.

Here's the constructor:

 ClassWizard::ClassWizard(QWidget *parent)
     : QWizard(parent)
 {
     addPage(new IntroPage);
     addPage(new ClassInfoPage);
     addPage(new CodeStylePage);
     addPage(new OutputFilesPage);
     addPage(new ConclusionPage);

     setPixmap(QWizard::BannerPixmap, QPixmap(":/images/banner.png"));
     setPixmap(QWizard::BackgroundPixmap, QPixmap(":/images/background.png"));

     setWindowTitle(tr("Class Wizard"));
 }

We instantiate the five pages and insert them into the wizard using QWizard::addPage(). The order in which they are inserted is also the order in which they will be shown later on.

We call QWizard::setPixmap() to set the banner and the background pixmaps for all pages. The banner is used as a background for the page header when the wizard's style is ModernStyle; the background is used as the dialog's background in MacStyle. (See Elements of a Wizard Page for more information.)

 void ClassWizard::accept()
 {
     QByteArray className = field("className").toByteArray();
     QByteArray baseClass = field("baseClass").toByteArray();
     QByteArray macroName = field("macroName").toByteArray();
     QByteArray baseInclude = field("baseInclude").toByteArray();

     QString outputDir = field("outputDir").toString();
     QString header = field("header").toString();
     QString implementation = field("implementation").toString();
     ...
     QDialog::accept();
 }

If the user clicks Finish, we extract the information from the various pages using QWizard::field() and generate the files. The code is long and tedious (and has barely anything to do with noble art of designing wizards), so most of it is skipped here. See the actual example in the Qt distribution for the details if you're curious.

The IntroPage Class

The pages are defined in classwizard.h and implemented in classwizard.cpp, together with ClassWizard. We will start with the easiest page:

 class IntroPage : public QWizardPage
 {
     Q_OBJECT

 public:
     IntroPage(QWidget *parent = 0);

 private:
     QLabel *label;
 };

 IntroPage::IntroPage(QWidget *parent)
     : QWizardPage(parent)
 {
     setTitle(tr("Introduction"));
     setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/watermark1.png"));

     label = new QLabel(tr("This wizard will generate a skeleton C++ class "
                           "definition, including a few functions. You simply "
                           "need to specify the class name and set a few "
                           "options to produce a header file and an "
                           "implementation file for your new C++ class."));
     label->setWordWrap(true);

     QVBoxLayout *layout = new QVBoxLayout;
     layout->addWidget(label);
     setLayout(layout);
 }

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.)

Then we create a QLabel and add it to a layout.

The ClassInfoPage Class

The second page is defined and implemented as follows:

 class ClassInfoPage : public QWizardPage
 {
     Q_OBJECT

 public:
     ClassInfoPage(QWidget *parent = 0);

 private:
     QLabel *classNameLabel;
     QLabel *baseClassLabel;
     QLineEdit *classNameLineEdit;
     QLineEdit *baseClassLineEdit;
     QCheckBox *qobjectMacroCheckBox;
     QGroupBox *groupBox;
     QRadioButton *qobjectCtorRadioButton;
     QRadioButton *qwidgetCtorRadioButton;
     QRadioButton *defaultCtorRadioButton;
     QCheckBox *copyCtorCheckBox;
 };

 ClassInfoPage::ClassInfoPage(QWidget *parent)
     : QWizardPage(parent)
 {
     setTitle(tr("Class Information"));
     setSubTitle(tr("Specify basic information about the class for which you "
                    "want to generate skeleton source code files."));
     setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo1.png"));

     classNameLabel = new QLabel(tr("&Class name:"));
     classNameLineEdit = new QLineEdit;
     classNameLabel->setBuddy(classNameLineEdit);

     baseClassLabel = new QLabel(tr("B&ase class:"));
     baseClassLineEdit = new QLineEdit;
     baseClassLabel->setBuddy(baseClassLineEdit);

     qobjectMacroCheckBox = new QCheckBox(tr("Generate Q_OBJECT &macro"));

     groupBox = new QGroupBox(tr("C&onstructor"));
     ...
     registerField("className*", classNameLineEdit);
     registerField("baseClass", baseClassLineEdit);
     registerField("qobjectMacro", qobjectMacroCheckBox);
     registerField("qobjectCtor", qobjectCtorRadioButton);
     registerField("qwidgetCtor", qwidgetCtorRadioButton);
     registerField("defaultCtor", defaultCtorRadioButton);
     registerField("copyCtor", copyCtorCheckBox);

     QVBoxLayout *groupBoxLayout = new QVBoxLayout;
     ...
 }

First, we set the page's title, subTitle, and logo pixmap. The logo pixmap is displayed in the page's header in ClassicStyle and ModernStyle.

Then we create the child widgets, create wizard fields associated with them, and put them into layouts. The className field is created with an asterisk (*) next to its name. This makes it a mandatory field, that is, a field 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(), or from the wizard code using QWizard::field().

The CodeStylePage Class

The third page is defined and implemented as follows:

 class CodeStylePage : public QWizardPage
 {
     Q_OBJECT

 public:
     CodeStylePage(QWidget *parent = 0);

 protected:
     void initializePage();

 private:
     QCheckBox *commentCheckBox;
     QCheckBox *protectCheckBox;
     QCheckBox *includeBaseCheckBox;
     QLabel *macroNameLabel;
     QLabel *baseIncludeLabel;
     QLineEdit *macroNameLineEdit;
     QLineEdit *baseIncludeLineEdit;
 };

 CodeStylePage::CodeStylePage(QWidget *parent)
     : QWizardPage(parent)
 {
     setTitle(tr("Code Style Options"));
     setSubTitle(tr("Choose the formatting of the generated code."));
     setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo2.png"));

     commentCheckBox = new QCheckBox(tr("&Start generated files with a "
     ...
     setLayout(layout);
 }

 void CodeStylePage::initializePage()
 {
     QString className = field("className").toString();
     macroNameLineEdit->setText(className.toUpper() + "_H");

     QString baseClass = field("baseClass").toString();

     includeBaseCheckBox->setChecked(!baseClass.isEmpty());
     includeBaseCheckBox->setEnabled(!baseClass.isEmpty());
     baseIncludeLabel->setEnabled(!baseClass.isEmpty());
     baseIncludeLineEdit->setEnabled(!baseClass.isEmpty());

     if (baseClass.isEmpty()) {
         baseIncludeLineEdit->clear();
     } else if (QRegExp("Q[A-Z].*").exactMatch(baseClass)) {
         baseIncludeLineEdit->setText("<" + baseClass + ">");
     } else {
         baseIncludeLineEdit->setText("\"" + baseClass.toLower() + ".h\"");
     }
 }

The code in the constructor is very similar to what we did for ClassInfoPage, so we skipped most of it.

The initializePage() function is what makes this class interesting. It is reimplemented from QWizardPage and is used to initialize some of the page's fields with values from the previous page (namely, className and baseClass). For example, if the class name on page 2 is SuperDuperWidget, the default macro name on page 3 is SUPERDUPERWIDGET_H.

The OutputFilesPage and ConclusionPage classes are very similar to CodeStylePage, so we won't review them here.

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

Publicité

Best Of

Actualités les plus lues

Semaine
Mois
Année
  1. « Quelque chose ne va vraiment pas avec les développeurs "modernes" », un développeur à "l'ancienne" critique la multiplication des bibliothèques 54
  2. Les développeurs ignorent-ils trop les failles découvertes dans leur code ? Prenez-vous en compte les remarques des autres ? 17
  3. Apercevoir la troisième dimension ou l'utilisation multithreadée d'OpenGL dans Qt, un article des Qt Quarterly traduit par Guillaume Belz 0
  4. 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
  5. Quelles nouveautés de C++11 Visual C++ doit-il rapidement intégrer ? Donnez-nous votre avis 10
  6. Adieu qmake, bienvenue qbs : Qt Building Suite, un outil déclaratif et extensible pour la compilation de projets Qt 17
  7. La rubrique Qt a besoin de vous ! 1
Page suivante

Le Qt Quarterly au hasard

Logo

FAQ sur l'internationalisation

Qt Quarterly est la revue trimestrielle proposée par Nokia et à destination des développeurs Qt. Ces articles d'une grande qualité technique sont rédigés par des experts Qt. Lire l'article.

Communauté

Ressources

Liens utiles

Contact

  • 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.7-snapshot
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 !
 
 
 
 
Partenaires

Hébergement Web