许可证向导例子演示了如何使用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(":/images/logo.png"));
connect(this, SIGNAL(helpRequested()), this, SLOT(showHelp()));
setWindowTitle(tr("License Wizard"));
}
我们给QWizard配置一个帮助按钮,这个按钮和showHelp()槽函数相连,我们也为所有拥有标题的页面设置一个LogoPixmap。(如: 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.");
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(":/images/watermark.png"));
topLabel = new QLabel(tr("This wizard will help you register your copy of "
"<i>Super Product One</i>™ 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()函数返回EvaluatePage的ID;否则返回RegisterPage的ID。