6.2 分组布局
QStackedLayout类可以对一组子窗口部件进行摆放,或者对它们进行“分页”,而且一次只显示其中一个,而把其他的子窗口部件或者分页都隐藏起来。QStackedLayout本身并不可见,并且对于用户改变分页也没有提供其他特有的方法。图6.5中的小箭头和暗灰色框架是由Qt设计师提供的,利用它们可以使布局设计变得更容易些。为方便起见,Qt还提供了QStackedWidget类,这个类提供了一个带内置QStackedLayout的QWidget。
分页是从0开始编号的。要使某个特定的子窗口部件可见,可以用一个页号来调用setCurrentIndex()。使用indexOf()可以获取子窗口部件的页号。
在图6.6中显示的Preferences对话框就是一个使用了QStackedIayout的例子。这个对话框由左侧的QListWidget和右侧的QStackedLayout构成。在QListWidget中的每一项,都分别对应于QStackedLayout中的不同页。这里给出了与这个对话框的构造函数相关的部分代码:
//preferencedialog.h
#ifndef PREFERENCEDIALOG_H
#define PREFERENCEDIALOG_H
#include <QDialog>
class QCheckBox;
class QDialogButtonBox;
class QGroupBox;
class QLabel;
class QLineEdit;
class QListWidget;
class QRadioButton;
class QStackedLayout;
class PreferenceDialog : public QDialog
{
Q_OBJECT
public:
PreferenceDialog(QWidget *parent = 0);
private:
void createAppearancePage();
void createWebBrowserPage();
void createMailAndNewsPage();
void createAdvancedPage();
QStackedLayout *stackedLayout;
QListWidget *listWidget;
QWidget *appearancePage;
QWidget *webBrowserPage;
QWidget *mailAndNewsPage;
QWidget *advancedPage;
QDialogButtonBox *buttonBox;
QGroupBox *openGroupBox;
QCheckBox *webBrowserCheckBox;
QCheckBox *mailEditorCheckBox;
QCheckBox *newsgroupCheckBox;
QGroupBox *toolbarsGroupBox;
QRadioButton *picturesAndTextRadioButton;
QRadioButton *picturesOnlyRadioButton;
QRadioButton *textOnlyRadioButton;
QCheckBox *tooltipsCheckBox;
QCheckBox *webSiteIconsCheckBox;
QCheckBox *resizeImagesCheckBox;
QGroupBox *displayGroupBox;
QRadioButton *blankRadioButton;
QRadioButton *homeRadioButton;
QRadioButton *lastRadioButton;
QGroupBox *homeGroupBox;
QLabel *locationLabel;
QLineEdit *locationLineEdit;
QGroupBox *webButtonsGroupBox;
QCheckBox *bookmarksCheckBox;
QCheckBox *goCheckBox;
QCheckBox *homeCheckBox;
QCheckBox *searchCheckBox;
QCheckBox *printCheckBox;
QGroupBox *generalGroupBox;
QCheckBox *confirmCheckBox;
QCheckBox *rememberCheckBox;
QGroupBox *mailButtonsGroupBox;
QCheckBox *fileCheckBox;
QCheckBox *nextCheckBox;
QCheckBox *stopCheckBox;
QCheckBox *junkCheckBox;
QGroupBox *featuresGroupBox;
QCheckBox *javaCheckBox;
QCheckBox *ftpCheckBox;
QLineEdit *ftpLineEdit;
};
#endif // PREFERENCEDIALOG_H
//preferencedialog.cpp
#include <QtWidgets>
#include "preferencedialog.h"
PreferenceDialog::PreferenceDialog(QWidget *parent)
: QDialog(parent)
{
createAppearancePage();
createWebBrowserPage();
createMailAndNewsPage();
createAdvancedPage();
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
| QDialogButtonBox::Cancel);
/* 我们创建一个QListWidget, 并且把它和这些分页的名字一起配合使用。
* 然后,创建一个QStackedLayout,并且对每一个分页分别调用addWidget()。
* 我们把这个列表窗口部件的currentRowChanged(int)信号连接到这个分组布局的setCurrentIndex(int),可以用来实现分页的切换操作,
* 并且在构造函数的最后,对这个列表窗口部件调用setCurrentRow(),这样就可以把页号0设置为起始页。
*/
listWidget = new QListWidget;
listWidget->addItem(tr("Appearance"));
listWidget->addItem(tr("Web Browser"));
listWidget->addItem(tr("Mail & News"));
listWidget->addItem(tr("Advanced"));
stackedLayout = new QStackedLayout;
stackedLayout->addWidget(appearancePage);
stackedLayout->addWidget(webBrowserPage);
stackedLayout->addWidget(mailAndNewsPage);
stackedLayout->addWidget(advancedPage);
connect(listWidget, SIGNAL(currentRowChanged(int)),
stackedLayout, SLOT(setCurrentIndex(int)));
QGridLayout *mainLayout = new QGridLayout;
mainLayout->setColumnStretch(0, 1);
mainLayout->setColumnStretch(1, 3);
mainLayout->addWidget(listWidget, 0, 0);
mainLayout->addLayout(stackedLayout, 0, 1);
mainLayout->addWidget(buttonBox, 1, 0, 1, 2);
setLayout(mainLayout);
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
setWindowTitle(tr("Preferences"));
listWidget->setCurrentRow(0);
}
void PreferenceDialog::createAppearancePage()
{
appearancePage = new QWidget;
openGroupBox = new QGroupBox(tr("Open at startup"));
webBrowserCheckBox = new QCheckBox(tr("Web browser"));
mailEditorCheckBox = new QCheckBox(tr("Mail editor"));
newsgroupCheckBox = new QCheckBox(tr("Newsgroups"));
toolbarsGroupBox = new QGroupBox(tr("Show toolbars as"));
picturesAndTextRadioButton = new QRadioButton(tr("Pictures and "
"text"));
pict