Class Wizard Example中是讲的线性结构的向导,License Wizard Example是复杂结构向导的一个简单例子。
例子由下面两部分组成:
1. LicenseWizard,它继承自QWizard,实现了一个非线性结构的5页向导。向导指导用户通过选择许可协议的程序。
2. IntroPage,EvaluatePage,RegisterPage,DetailsPage和ConclusionPage,他们都是QWizardPage的子类,实现一个向导页。
这个例子有许多明显的问题,不过不要认真,你认真就输了 ^ ^
本例中使用重新实现nextId()来指定下一页,从而改变线性的向导结构。使用setPage(id, page)的方式添加向导页则为之设置了id。setStartId则设置开始页。
另外setOption(WizardOption option, bool on = true) 来设置一些选项,例如可增加帮助按钮:setOption(HaveHelpButton, true);
WizardOption有许多枚举值项,可查帮助文档。
那么开始看代码吧~
int main(int argc, char *argv[]) { Q_INIT_RESOURCE(licensewizard); QApplication app(argc, argv); // 国际化支持 QString translatorFileName = QLatin1String("qt_"); translatorFileName += QLocale::system().name(); // 返回语言和国家"language_country" QTranslator *translator = new QTranslator(&app); if (translator->load(translatorFileName, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) app.installTranslator(translator); LicenseWizard wizard; wizard.show(); return app.exec(); }
//! [0] //! [1] // LicenseWizard需要通过ID来调用页的先后顺序,则为页都提供一个枚举值 class LicenseWizard : public QWizard { //! [0] Q_OBJECT public: //! [2] enum { Page_Intro, Page_Evaluate, Page_Register, Page_Details, Page_Conclusion }; // 定义一个枚举类作为标识 //! [2] LicenseWizard(QWidget *parent = 0); private slots: void showHelp(); // 自定义个一个槽,用以弹出帮助说明 //! [3] }; //! [1] //! [3] //! [4] // IntroPage页,一个topLabel显示说明,两个RadioButton指导下一步走向 // 需要重新实现nextId() class IntroPage : public QWizardPage { Q_OBJECT public: IntroPage(QWidget *parent = 0); int nextId() const; private: QLabel *topLabel; QRadioButton *registerRadioButton; QRadioButton *evaluateRadioButton; }; //! [4] //! [5] // Evaluate页,包含两对label两对lineEdit class EvaluatePage : public QWizardPage { Q_OBJECT public: EvaluatePage(QWidget *parent = 0); int nextId() const; private: QLabel *nameLabel; QLabel *emailLabel; QLineEdit *nameLineEdit; QLineEdit *emailLineEdit; }; //! [5] // 验证Key页面 class RegisterPage : public QWizardPage { Q_OBJECT public: RegisterPage(QWidget *parent = 0); int nextId() const; private: QLabel *nameLabel; QLabel *upgradeKeyLabel; QLineEdit *nameLineEdit; QLineEdit *upgradeKeyLineEdit; }; // Details页,三对label-lineEdit class DetailsPage : public QWizardPage { Q_OBJECT public: DetailsPage(QWidget *parent = 0); int nextId() const; private: QLabel *companyLabel; QLabel *emailLabel; QLabel *postalLabel; QLineEdit *companyLineEdit; QLineEdit *emailLineEdit; QLineEdit *postalLineEdit; }; //! [6] // 最后一页提供打印协议 // 重新实现setVisible,让打印按钮动态创建 class ConclusionPage : public QWizardPage { Q_OBJECT public: ConclusionPage(QWidget *parent = 0); void initializePage(); int nextId() const; void setVisible(bool visible); private slots: void printButtonClicked(); private: QLabel *bottomLabel; QCheckBox *agreeCheckBox; }; //! [6]
//! [0] //! [1] //! [2] LicenseWizard::LicenseWizard(QWidget *parent) : QWizard(parent) { //! [0] // 依次添加5页,枚举值与向导页实例对应 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); //! [1] // 设置开始页 setStartId(Page_Intro); // Page_Intro为枚举值 //! [2] //! [3] #ifndef Q_WS_MAC //! [3] //! [4] setWizardStyle(ModernStyle); #endif //! [4] //! [5] setOption(HaveHelpButton, true); //! [5] //! [6] setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo.png")); //! [7] connect(this, SIGNAL(helpRequested()), this, SLOT(showHelp())); //! [7] setWindowTitle(tr("License Wizard")); //! [8] } //! [6] //! [8] //! [9] //! [10] void LicenseWizard::showHelp() //! [9] //! [11] { 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; //! [10] //! [11] case Page_Evaluate: message = tr("Make sure to provide a valid email address, such as " "[email protected]."); break; case Page_Register: message = tr("If you don't provide an upgrade key, you will be " "asked to fill in your details."); break; case Page_Details: message = tr("Make sure to provide a valid email address, such as " "[email protected]."); break; case Page_Conclusion: message = tr("You must accept the terms and conditions of the " "license to proceed."); break; //! [12] //! [13] default: message = tr("This help is likely not to be of any help."); } //! [12] if (lastHelpMessage == message) // 同一页面点击帮助偶数次 message = tr("Sorry, I already gave what help I could. " "Maybe you should try asking a human?"); //! [14] // 弹出信息对话框 QMessageBox::information(this, tr("License Wizard Help"), message); //! [14] lastHelpMessage = message; //! [15] } //! [13] //! [15] //! [16] 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); } //! [16] //! [17] //! [18] // 指示下一页ID int IntroPage::nextId() const //! [17] //! [19] { if (evaluateRadioButton->isChecked()) { // 根据单选按钮选中下一页 return LicenseWizard::Page_Evaluate; } else { return LicenseWizard::Page_Register; } } //! [18] //! [19] //! [20] EvaluatePage::EvaluatePage(QWidget *parent) : QWizardPage(parent) { setTitle(tr("Evaluate <i>Super Product One</i>™")); setSubTitle(tr("Please fill both fields. Make sure to provide a valid " "email address (e.g., [email protected]).")); nameLabel = new QLabel(tr("N&ame:")); // 创建页内的窗体部件 nameLineEdit = new QLineEdit; //! [20] nameLabel->setBuddy(nameLineEdit); //label和lineEdit绑定 emailLabel = new QLabel(tr("&Email address:")); emailLineEdit = new QLineEdit; // 用正则表达式指定需带@符号,用QRegExpValidator检查输入字符是否符合要求 emailLineEdit->setValidator(new QRegExpValidator(QRegExp(".*@.*"), this)); emailLabel->setBuddy(emailLineEdit); //! [21] registerField("evaluate.name*", nameLineEdit); // 两个lineEdit都注册成托管域 registerField("evaluate.email*", emailLineEdit); // 只有将本页的托管域都填好了才能进入下一页 //! [21] QGridLayout *layout = new QGridLayout; // 布局 layout->addWidget(nameLabel, 0, 0); layout->addWidget(nameLineEdit, 0, 1); layout->addWidget(emailLabel, 1, 0); layout->addWidget(emailLineEdit, 1, 1); setLayout(layout); //! [22] } //! [22] //! [23] int EvaluatePage::nextId() const { return LicenseWizard::Page_Conclusion; // 指示下一页 } //! [23] // 验证Key RegisterPage::RegisterPage(QWidget *parent) : QWizardPage(parent) { setTitle(tr("Register Your Copy of <i>Super Product One</i>™")); setSubTitle(tr("If you have an upgrade key, please fill in " "the appropriate field.")); nameLabel = new QLabel(tr("N&ame:")); nameLineEdit = new QLineEdit; nameLabel->setBuddy(nameLineEdit); upgradeKeyLabel = new QLabel(tr("&Upgrade key:")); upgradeKeyLineEdit = new QLineEdit; upgradeKeyLabel->setBuddy(upgradeKeyLineEdit); // 设置域 registerField("register.name*", nameLineEdit); // 将注册名作为托管域 registerField("register.upgradeKey", upgradeKeyLineEdit); QGridLayout *layout = new QGridLayout; // 布局 layout->addWidget(nameLabel, 0, 0); layout->addWidget(nameLineEdit, 0, 1); layout->addWidget(upgradeKeyLabel, 1, 0); layout->addWidget(upgradeKeyLineEdit, 1, 1); setLayout(layout); } //! [24] int RegisterPage::nextId() const { if (upgradeKeyLineEdit->text().isEmpty()) { // 简单判断key来确定下一页 return LicenseWizard::Page_Details; } else { return LicenseWizard::Page_Conclusion; } } //! [24] DetailsPage::DetailsPage(QWidget *parent) : QWizardPage(parent) { // 标题与子标题 setTitle(tr("Fill In Your Details")); setSubTitle(tr("Please fill all three fields. Make sure to provide a valid " "email address (e.g., [email protected]).")); // 创建label-lineEdit companyLabel = new QLabel(tr("&Company name:")); companyLineEdit = new QLineEdit; companyLabel->setBuddy(companyLineEdit); emailLabel = new QLabel(tr("&Email address:")); emailLineEdit = new QLineEdit; emailLineEdit->setValidator(new QRegExpValidator(QRegExp(".*@.*"), this)); // 格式过滤 emailLabel->setBuddy(emailLineEdit); postalLabel = new QLabel(tr("&Postal address:")); postalLineEdit = new QLineEdit; postalLabel->setBuddy(postalLineEdit); // 注册域 registerField("details.company*", companyLineEdit); registerField("details.email*", emailLineEdit); registerField("details.postal*", postalLineEdit); QGridLayout *layout = new QGridLayout; // 布局 layout->addWidget(companyLabel, 0, 0); layout->addWidget(companyLineEdit, 0, 1); layout->addWidget(emailLabel, 1, 0); layout->addWidget(emailLineEdit, 1, 1); layout->addWidget(postalLabel, 2, 0); layout->addWidget(postalLineEdit, 2, 1); setLayout(layout); } //! [25] int DetailsPage::nextId() const { return LicenseWizard::Page_Conclusion; // 指示下一页为conclusion页 } //! [25] ConclusionPage::ConclusionPage(QWidget *parent) : QWizardPage(parent) { // 设置标题与左侧图片 setTitle(tr("Complete Your Registration")); setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/watermark.png")); bottomLabel = new QLabel; // 一个说明标签 bottomLabel->setWordWrap(true); // checkBox指示是否同意协议,同意了才能让你点击完成 agreeCheckBox = new QCheckBox(tr("I agree to the terms of the license")); registerField("conclusion.agree*", agreeCheckBox); // 注册域 QVBoxLayout *layout = new QVBoxLayout; // 竖直布局 layout->addWidget(bottomLabel); layout->addWidget(agreeCheckBox); setLayout(layout); } //! [26] int ConclusionPage::nextId() const // 没有下一页了 { return -1; } //! [26] //! [27] // ConclusionPage前一页点击Next后调用本槽 void ConclusionPage::initializePage() // { QString licenseText; // 根据上一页的不同ID来决定说明标签里的内容 //wizard()返回与本页相关联的向导; hasVisitedPage(id)是否访问id页 if (wizard()->hasVisitedPage(LicenseWizard::Page_Evaluate)) { // 如果来自EvaluatePage 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)) { // 如果来自EetailsPage licenseText = tr("<u>First-Time License Agreement:</u> " "You can use this software subject to the license " "you will receive by email."); } else { // 如果来自RegisterPage licenseText = tr("<u>Upgrade License Agreement:</u> " "This software is licensed under the terms of your " "current license."); } bottomLabel->setText(licenseText); } //! [27] //! [28] // 设置打印按钮 void ConclusionPage::setVisible(bool visible) { QWizardPage::setVisible(visible); if (visible) { // 可见,就创建Print按钮 //! [29] wizard()->setButtonText(QWizard::CustomButton1, tr("&Print")); wizard()->setOption(QWizard::HaveCustomButton1, true); // 设置第一个自定义按钮 connect(wizard(), SIGNAL(customButtonClicked(int)), // 连接信号槽 this, SLOT(printButtonClicked())); //! [29] } else { wizard()->setOption(QWizard::HaveCustomButton1, false); disconnect(wizard(), SIGNAL(customButtonClicked(int)), // 隐藏则断开连接 this, SLOT(printButtonClicked())); } } //! [28] void ConclusionPage::printButtonClicked() // 打印License { QPrinter printer; QPrintDialog dialog(&printer, this); if (dialog.exec()) // 以弹出对话框代替打印 QMessageBox::warning(this, tr("Print License"), tr("As an environmentally friendly measure, the " "license text will not actually be printed.")); }