许可证向导例子演示了如何使用Qt实现复杂的向导。

大多数向导为线性结构,第1页、第2页,依次类推只到最后一页。类向导的例子说明了如何创建这样的向导。

有些向导比较复杂,它们允许遍历不同的由用户提供的信息为基础的路径。许可证向导的例子说明了这一点。它提供了5个向导页,根据选中的选项,用户可以访问不同的页面。

该例子包含以下类:

l  LicenseWizard类从QWizard类继承,实现了一个非线性、共5页的向导,引导用户完成许可协议的选择。

l  IntroPage, EvaluatePage, RegisterPage, DetailsPage, ConclusionPage类是QWizardPage的子类,它们实现了各个向导页。

LicenseWizard

LicenseWizard类从QWizard继承,并提供了一个五页的向导,指导用户完成一个虚拟软件产品的副本的注册工作。下面是类的定义:

class LicenseWizard : public QWizard

 {

     Q_OBJECT


 public:

     enum { Page_Intro, Page_Evaluate, Page_Register, Page_Details,

            Page_Conclusion };


     LicenseWizard(QWidget *parent = 0);


 private slots:

     void showHelp();

 };

类的公共接口只有构造函数和一个枚举类。枚举类定义了和各个页面相关的ID

Class name

Enum value

Page ID

IntroPage

Page_Intro

0

EvaluatePage

Page_Evaluate

1

RegisterPage

Page_Register

2

DetailsPage

Page_Details

3

ConclusionPage

Page_Conclusion

4

 

在这个例子中,ID是任意的,对这些ID的唯一限制是它们必须唯一,且不能为-1;通过ID我们可以访问页面。

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


     setStartId(Page_Intro);

在构造函数中,我们创建了5个页面,通过QWizard::setPage()函数将这些页面添加到向导中,并设置Page_Intro为第一页。

 #ifndef Q_WS_MAC

     setWizardStyle(ModernStyle);

 #endif

除了Mac OS系统外,在其它所有平台上我们将向导设置为ModernStyle 风格

setOption(HaveHelpButton, true);

     setPixmap(QWizard::LogoPixmap, QPixmap(":/p_w_picpaths/logo.png"));


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


     setWindowTitle(tr("License Wizard"));

 }

我们给QWizard配置一个帮助按钮,这个按钮和showHelp()槽函数相连,我们也为所有拥有标题的页面设置一个LogoPixmap(如: EvaluatePageRegisterPage, 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.");

         break;

     ...

     default:

         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;

 }

showHelp()函数中,我们为当前页面显示合适的帮助文本。如果用户在同一个页面上点击了两次帮助按钮,程序会提示“Sorry, I already gave what help I could. Maybe you should try asking a human?”。

IntroPage

所有页面类和LicenseWizard类在licensewizard.h中定义,在icensewizard.cpp中实现。

以下是IntroPage的定义和实现:

class IntroPage : public QWizardPage

 {

     Q_OBJECT


 public:

     IntroPage(QWidget *parent = 0);


     int nextId() const;


 private:

     QLabel *topLabel;

     QRadioButton *registerRadioButton;

     QRadioButton *evaluateRadioButton;

 };

 

 IntroPage::IntroPage(QWidget *parent)

     : QWizardPage(parent)

 {

     setTitle(tr("Introduction"));

     setPixmap(QWizard::WatermarkPixmap, QPixmap(":/p_w_picpaths/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."));

     topLabel->setWordWrap(true);


     registerRadioButton = new QRadioButton(tr("&Register your copy"));

     evaluateRadioButton = new QRadioButton(tr("&Evaluate the product for 30 "

                                               "days"));

     registerRadioButton->setChecked(true);


     QVBoxLayout *layout = new QVBoxLayout;

     layout->addWidget(topLabel);

     layout->addWidget(registerRadioButton);

     layout->addWidget(evaluateRadioButton);

     setLayout(layout);

 }

QWzardPage类继承的页面类。我们设置一个标题和一个watermarkPixmap,不设置任何副标题,我们确保该页不显示任何标题。(windows上,习惯在向导的第一页和最后一页显示一个watermarkPixmap,在其它页面上显示标题)

int IntroPage::nextId() const

 {

     if (evaluateRadioButton->isChecked()) {

         return LicenseWizard::Page_Evaluate;

     } else {

         return LicenseWizard::Page_Register;

     }

 }

如果Evaluate the product for 30 days选项被选中,nextId()函数返回EvaluatePageID;否则返回RegisterPageID