文章目录
QWizard Class
QWizard类为向导提供了一个框架。
Header | #include < QWizard > |
---|---|
qmake | QT += widgets |
Inherits | QDialog |
Inherited By |
详细说明
向导(在macOS上也称为助手)是一种特殊类型的输入对话框,由一系列页面组成。向导的目的是引导用户逐步完成一个过程。向导对于复杂或不频繁的任务非常有用,用户可能会发现这些任务很难学习。
QWizard继承QDialog并表示一个向导。每个页面都是一个QWizardPage(QWidget子类)。要创建自己的向导,可以直接使用这些类,也可以对它们进行子类化以获得更多控制。
话题:
一个微不足道的例子
下面的示例演示如何创建向导页并将其添加到向导中。
QWizardPage *createIntroPage()
{
QWizardPage *page = new QWizardPage;
page->setTitle("Introduction");
QLabel *label = new QLabel("This wizard will help you register your copy "
"of Super Product Two.");
label->setWordWrap(true);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(label);
page->setLayout(layout);
return page;
}
QWizardPage *createRegistrationPage()
{
...
}
QWizardPage *createConclusionPage()
{
...
}
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication app(argc, argv);
#ifndef QT_NO_TRANSLATION
QString translatorFileName = QLatin1String("qtbase_");
translatorFileName += QLocale::system().name();
QTranslator *translator = new QTranslator(&app);
if (translator->load(translatorFileName, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
app.installTranslator(translator);
#endif
QWizard wizard;
wizard.addPage(createIntroPage());
wizard.addPage(createRegistrationPage());
wizard.addPage(createConclusionPage());
wizard.setWindowTitle("Trivial Wizard");
wizard.show();
return app.exec();
}
向导外观
QWizard支持四种向导外观:
- ClassicStyle
- ModernStyle
- MacStyle
- AeroStyle
可以使用setWizardStyle() 显式设置要使用的外观(例如,如果希望在所有平台上使用相同的外观)。
ClassicStyle | ModernStyle | MacStyle | AeroStyle |
---|---|---|---|
注意:AeroStyle仅对启用alpha合成的Windows Vista系统有效。当不满足此条件时,ModernStyle用作回退。
除了向导样式之外,还有几个选项可以控制向导的外观。可以使用setOption() 或setOptions() 设置这些选项。例如,HaveHelpButton使QWizard显示一个帮助按钮以及其他向导按钮。
您甚至可以使用setButtonLayout() 将向导按钮的顺序更改为任意顺序,并且最多可以向按钮行添加三个自定义按钮(例如,打印按钮)。这是通过使用CustomButton1、CustomButton2或CustomButton3调用setButton() 或setButtonText() 来设置按钮,并通过启用HaveCustomButton1、HaveCustomButton2或HaveCustomButton3选项来实现的。每当用户单击自定义按钮时,都会发出customButtonClicked() 。例如:
wizard()->setButtonText(QWizard::CustomButton1, tr("&Print"));
wizard()->setOption(QWizard::HaveCustomButton1, true);
connect(wizard(), &QWizard::customButtonClicked,
this, &ConclusionPage::printButtonClicked);
向导页的元素
向导由一系列的QWizardPages组成。任何时候,只显示一页。页面具有以下属性:
-
标题。
-
副标题。
-
一组pixmap,根据向导的样式,可以使用,也可以不使用:
- 水印PixMap(由ClassicStyle和ModernStyle使用)
- BannerPixmap(ModernStyle使用)
- LogoPixmap(由ClassicStyle和ModernStyle使用)
- BackgroundPixmap(MacStyle使用)
下图显示了QWizard如何呈现这些属性,假设它们都存在并且使用了ModernStyle:
设置字幕后,QWizard会将其显示在标题中,在这种情况下,它还会使用BannerPixmap和LogoPixmap来装饰标题。水印pixmap显示在左侧标题下方。在底部,有一行按钮允许用户浏览页面。
页面本身(QWizardPage小部件)占据了标题、水印和按钮行之间的区域。通常,该页面是安装了QGridLayout的QWizardPage,带有标准的子窗口小部件(qlabel、QLineEdits等)。
如果向导的样式为MacStyle,则页面看起来完全不同:
MacStyle将忽略水印、横幅和徽标像素贴图。如果设置了BackgroundPixmap,则将其用作向导的背景;否则,将使用默认的“助手”图像。
通过在各个页面上调用QWizardPage::setTitle() 和QWizardPage::setSubTitle() 来设置标题和副标题。它们可以是纯文本或HTML(参见标题格式和副标题格式)。可以使用setPixmap() 为整个向导全局设置pixmap,也可以使用QWizardPage::setPixmap() 按页设置pixmap。
注册和使用字段
在许多向导中,页面内容可能会影响后面页面字段的默认值。为了方便页面之间的通信,QWizard支持“字段”机制,允许您在页面上注册字段(例如QLineEdit)并从任何页面访问其值。还可以指定强制字段(即,在用户可以进入下一页之前必须填写的字段)。
要注册字段,请调用QWizardPage::registerField()字段。例如:
ClassInfoPage::ClassInfoPage(QWidget *parent)
: QWizardPage(parent)
{
...
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 ¯o"));
registerField("className*", classNameLineEdit);
registerField("baseClass", baseClassLineEdit);
registerField("qobjectMacro", qobjectMacroCheckBox);
...
}
上面的代码注册了三个字段,className、baseClass和qobjectMacro,它们与三个子部件相关联。类名旁边的星号(*)表示强制字段。
任何页面的字段都可以从任何其他页面访问。例如:
void OutputFilesPage::initializePage()
{
QString className = field("className").toString();
headerLineEdit->setText(className.toLower() + ".h");
implementationLineEdit->setText(className.toLower() + ".cpp");
outputDirLineEdit->setText(QDir::toNativeSeparators(QDir::tempPath()));
}
在这里,我们调用QWizardPage::field()来访问className字段(在ClassInfoPage中定义)的内容,并使用它初始化OutputFilePage。字段的内容作为QVariant返回。
当我们使用QWizardPage::registerField()创建字段时,我们传递一个唯一的字段名和一个小部件。我们还可以提供一个Qt属性名和一个“changed”信号(属性更改时发出的信号)作为第三个和第四个参数;但是,对于最常见的Qt小部件,如QLineEdit、QCheckBox和QComboBox,这不是必需的,因为QWizard知道要查找哪些属性。
如果在注册属性时在名称后附加了星号(*),则该字段是必填字段。当页面包含必填字段时,仅当所有必填字段都已填写时,才会启用“下一步”和/或“完成”按钮。
要考虑字段“已填充”,QWizard只需检查字段的当前值是否不等于原始值(调用initializePage()时的值)。对于QLineEdit和QAbstractSpinBox子类,QWizard还检查hasAcceptableInput()是否返回true,以接受任何验证器或掩码。
为了方便起见,提供了QWizard的强制字段机制。一个更强大(但也更麻烦)的替代方法是重新实现QWizardPage::isComplete(),并在页面完成或不完整时发出QWizardPage::completeChanged()信号。
“下一步”和/或“完成”按钮的启用/禁用状态是对用户输入执行验证的一种方法。另一种方法是重新实现validateCurrentPage()(或QWizardPage::validatePage())以执行最后一分钟的验证(如果用户输入了不完整或无效的信息,则显示错误消息)。如果函数返回true,则显示下一页(或向导完成);否则,当前页将保留。
创建线性向导
大多数向导都有一个线性结构,第1页后接第2页,依此类推直到最后一页。类向导示例就是这样一个向导。使用QWizard,通过实例化QWizardPages并使用addPage()插入它们来创建线性向导。默认情况下,页面按添加顺序显示。例如:
ClassWizard::ClassWizard(QWidget *parent)
: QWizard(parent)
{
addPage(new IntroPage);
addPage(new ClassInfoPage);
addPage(new CodeStylePage);
addPage(new OutputFilesPage);
addPage(new ConclusionPage);
...
}
当一个页面即将显示时,QWizard调用initializePage()(它反过来调用QWizardPage::initializePage())用默认值填充该页面。默认情况下,此函数不执行任何操作,但可以重新实现,以便根据其他页面的字段初始化页面的内容(请参见上面的示例)。
如果用户按Back键,则会调用cleanupPage()(这又会调用QWizardPage::cleanupPage())。默认实现将页的字段重置为其原始值(调用initializePage()之前的值)。如果希望Back按钮是非破坏性的,并保留用户输入的值,只需启用IndependentPages选项。
创建非线性向导
有些向导更复杂,因为它们允许基于用户提供的信息的不同遍历路径。许可证向导示例说明了这一点。它提供了五个向导页面;根据选择的选项,用户可以访问不同的页面。
在复杂向导中,页由id标识。这些ID通常使用枚举定义。例如:
class LicenseWizard : public QWizard
{
...
enum { Page_Intro, Page_Evaluate, Page_Register, Page_Details,
Page_Conclusion };
...
};
使用setPage()插入页面,setPage()接受QWizardPage(或子类)的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);
...
}
默认情况下,页面按ID递增顺序显示。要根据用户选择的选项提供动态顺序,必须重新实现QWizardPage::nextId()。例如:
int IntroPage::nextId() const
{
if (evaluateRadioButton->isChecked()) {
return LicenseWizard::Page_Evaluate;
} else {
return LicenseWizard::Page_Register;
}
}
int EvaluatePage::nextId() const
{
return LicenseWizard::Page_Conclusion;
}
int RegisterPage::nextId() const
{
if (upgradeKeyLineEdit->text().isEmpty()) {
return LicenseWizard::Page_Details;
} else {
return LicenseWizard::Page_Conclusion;
}
}
int DetailsPage::nextId() const
{
return LicenseWizard::Page_Conclusion;
}
int ConclusionPage::nextId() const
{
return -1;
}
也可以将所有逻辑放在一个地方,在QWizard::nextId()重新实现中。例如:
int LicenseWizard::nextId() const
{
switch (currentId()) {
case Page_Intro:
if (field("intro.evaluate").toBool()) {
return Page_Evaluate;
} else {
return Page_Register;
}
case Page_Evaluate:
return Page_Conclusion;
case Page_Register:
if (field("register.upgradeKey").toString().isEmpty()) {
return Page_Details;
} else {
return Page_Conclusion;
}
case Page_Details:
return Page_Conclusion;
case Page_Conclusion:
default:
return -1;
}
}
要从ID最低的页面以外的其他页面开始,请调用setStartId()。
要测试页面是否已被访问,请调用hasVisitedPage()。例如:
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.");
}
bottomLabel->setText(licenseText);
}
公共类型
enum WizardButton
此枚举指定向导中的按钮。
Constant | Value | Description |
---|---|---|
QWizard::BackButton | 0 | 后退按钮(在macOS上返回) |
QWizard::NextButton | 1 | 下一步按钮(在macOS上继续) |
QWizard::CommitButton | 2 | “提交”按钮 |
QWizard::FinishButton | 3 | 完成按钮(在macOS上完成) |
QWizard::CancelButton | 4 | 取消按钮(另请参阅NoCancelButton) |
QWizard::HelpButton | 5 | 帮助按钮(另请参见HaveHelpButton) |
QWizard::CustomButton1 | 6 | 第一个用户定义的按钮(另请参见HaveCustomButton1) |
QWizard::CustomButton2 | 7 | 第二个用户定义的按钮(另请参见HaveCustomButton2) |
QWizard::CustomButton3 | 8 | 第三个用户定义按钮(另请参见HaveCustomButton3) |
以下值仅在调用setButtonLayout()时有用:
Constant | Value | Description |
---|---|---|
QWizard::Stretch | 9 | 按钮布局中的水平拉伸 |
enum WizardOption
flags WizardOptions
此枚举指定影响向导外观的各种选项。
Constant | Value | Description |
---|---|---|
QWizard::IndependentPages | 0x00000001 | 页面彼此独立(即,它们不从彼此派生值)。 |
QWizard::IgnoreSubTitles | 0x00000002 | 即使设置了字幕,也不要显示字幕。 |
QWizard::ExtendedWatermarkPixmap | 0x00000004 | 将任何水印像素贴图一直延伸到窗口的边缘。 |
QWizard::NoDefaultButton | 0x00000008 | 不要使“下一步”或“完成”按钮成为对话框的默认按钮。 |
QWizard::NoBackButtonOnStartPage | 0x00000010 | 不要在开始页上显示后退按钮。 |
QWizard::NoBackButtonOnLastPage | 0x00000020 | 不要在最后一页显示后退按钮。 |
QWizard::DisabledBackButtonOnLastPage | 0x00000040 | 禁用最后一页上的后退按钮。 |
QWizard::HaveNextButtonOnLastPage | 0x00000080 | 在最后一页显示(禁用的)下一步按钮。 |
QWizard::HaveFinishButtonOnEarlyPages | 0x00000100 | 在非最终页面上显示(禁用的)完成按钮。 |
QWizard::NoCancelButton | 0x00000200 | 不显示“取消”按钮。 |
QWizard::CancelButtonOnLeft | 0x00000400 | 将“取消”按钮放在后面的左侧(而不是“完成”或“下一步”的右侧)。 |
QWizard::HaveHelpButton | 0x00000800 | 显示“帮助”按钮。 |
QWizard::HelpButtonOnRight | 0x00001000 | 将“帮助”按钮放在按钮布局的最右侧(而不是最左侧)。 |
QWizard::HaveCustomButton1 | 0x00002000 | 显示第一个用户定义的按钮(CustomButton1)。 |
QWizard::HaveCustomButton2 | 0x00004000 | 显示第二个用户定义的按钮(CustomButton2)。 |
QWizard::HaveCustomButton3 | 0x00008000 | 显示第三个用户定义的按钮(CustomButton3)。 |
QWizard::NoCancelButtonOnLastPage | 0x00010000 | 不要在最后一页显示“取消”按钮。 |
enum WizardPixmap
此枚举指定可以与页关联的像素映射。
Constant | Value | Description |
---|---|---|
QWizard::WatermarkPixmap | 0 | ClassicStyle或ModernStyle页面左侧的高像素地图 |
QWizard::LogoPixmap | 1 | ClassicStyle或ModernStyle页眉右侧的小pixmap |
QWizard::BannerPixmap | 2 | 占据ModernStyle页眉背景的pixmap |
QWizard::BackgroundPixmap | 3 | 占据MacStyle向导背景的pixmap |
enum WizardStyle
此枚举指定QWizard支持的不同外观。
Constant | Value | Description |
---|---|---|
QWizard::ClassicStyle | 0 | 经典Windows外观 |
QWizard::ModernStyle | 1 | 现代窗户造型 |
QWizard::MacStyle | 2 | macOS外观 |
QWizard::AeroStyle | 3 | Windows Aero外观 |
属性
-
currentId: const int 当前页的ID
不能直接设置此属性。要更改当前页,请调用next()、back()或restart()。
默认情况下,此属性的值为-1,表示当前未显示任何页面。
- int currentId() const
Notifier signal:
- void currentIdChanged(int id)
-
options: WizardOptions 影响向导外观的各种选项
默认情况下,将设置以下选项(取决于平台):
- Windows:帮助按钮右侧。
- macOS : NoDefaultButton和NoCancelButton。
- X11和QWS(嵌入式Linux的Qt):无。
Access functions:
- QWizard::WizardOptions options() const
- void setOptions(QWizard::WizardOptions options)
-
startId: int 第一页的ID
如果未显式设置此属性,则此属性默认为此向导中的最低页ID,如果尚未插入任何页,则为-1。
- int startId() const
- void setStartId(int id)
-
subTitleFormat: Qt::TextFormat 页面副标题使用的文本格式
默认值 Qt::AutoText
- Qt::TextFormat subTitleFormat() const
- void setSubTitleFormat(Qt::TextFormat format)
-
titleFormat: Qt::TextFormat 保存页面标题使用的文本格式
默认格式为Qt :: AutoText。
- Qt::TextFormat titleFormat() const
- void setTitleFormat(Qt::TextFormat format)
-
wizardStyle: WizardStyle 向导的外观
默认情况下,无论当前的窗口小部件样式如何,QWizard都在启用了alpha合成的Windows Vista系统上使用AeroStyle。 如果不是这种情况,则默认的向导样式取决于当前的小部件样式,如下所示:如果当前的小部件样式为QMacStyle,则MacStyle为默认值;如果当前的小部件样式为QWindowsStyle,则ModernStyle为默认值; 所有其他情况。
- QWizard::WizardStyle wizardStyle() const
- void setWizardStyle(QWizard::WizardStyle style)
公共函数
构造和析构
- QWizard(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags())
- virtual ~QWizard()
属性相关
- int currentId() const
- QWizard::WizardOptions options() const
void setOptions(QWizard::WizardOptions options) - int startId() const
void setStartId(int id) - Qt::TextFormat subTitleFormat() const
void setSubTitleFormat(Qt::TextFormat format) - Qt::TextFormat titleFormat() const
void setTitleFormat(Qt::TextFormat format) - QWizard::WizardStyle wizardStyle() const
void setWizardStyle(QWizard::WizardStyle style)
其它
-
int addPage(QWizardPage *page)
void setPage(int id, QWizardPage *page)
void removePage(int id)
QWizardPage * page(int id) const -
QAbstractButton * button(QWizard::WizardButton which) const
void setButton(QWizard::WizardButton which, QAbstractButton *button) -
QString buttonText(QWizard::WizardButton which) const
void setButtonText(QWizard::WizardButton which, const QString &text) -
QWizardPage * currentPage() const
virtual bool validateCurrentPage() -
QVariant field(const QString &name) const
void setField(const QString &name, const QVariant &value) -
bool hasVisitedPage(int id) const
QList< int> visitedIds() const -
virtual int nextId() const
QList< int> pageIds() const -
QPixmap pixmap(QWizard::WizardPixmap which) const
void setPixmap(QWizard::WizardPixmap which, const QPixmap &pixmap) -
bool testOption(QWizard::WizardOption option) const
void setOption(QWizard::WizardOption option, bool on = true) -
QWidget * sideWidget() const
void setSideWidget(QWidget *widget) -
void setButtonLayout(const QList< QWizard::WizardButton > &layout)
-
void setDefaultProperty(const char *className, const char *property, const char *changedSignal)
重写的公共函数
- virtual void setVisible(bool visible) override
- virtual QSize sizeHint() const override
公共槽
- void back()
- void next()
- void restart()
信号
- void currentIdChanged(int id)
- void customButtonClicked(int which)
- void helpRequested()
- void pageAdded(int id)
- void pageRemoved(int id)
受保护的函数
- virtual void cleanupPage(int id)
- virtual void initializePage(int id)
重写的受保护的函数
- virtual void done(int result) override
- virtual bool event(QEvent *event) override
- virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result) override
- virtual void paintEvent(QPaintEvent *event) override
- virtual void resizeEvent(QResizeEvent *event) override
参考
有关更高级的示例,请参阅类向导和许可证向导。
- 类向导 Class Wizard
- 许可证向导 License Wizard