7.4 常见内建(built in)对话框的使用

优质
小牛编辑
128浏览
2023-12-01

内建对话框又被称为是标准对话框。Qt 提供了一整套内置的窗口部件和常用对话框, 如文件选择、字体选择、颜色选择、消息提示对话框等,它们为应用程序提供了与本地平台 一致的观感,可以满足大多数情况下的使用需求。Qt 对这些标准对话框都定义了相应的 类,使用者可以很方便的使用它们。标准对话框在软件设计过程中使经常需要使用的,必须 熟练掌握。

下面我们首先介绍 QInputDialog 、QColorDialog、QFontDialog、、QMessageBox 这 几种标准对话框的使用要领,然后再通过一个实例做示范。

7.4.1 标准输入框(QInputDialog)

本小节讲解如何使用标准输入框。在 Qt 中,构建标准输入框通常使用 QinputDialog 类。QInputDialog 类提供了一种简单方便的对话框来获得用户的单个输入信息。目前 Qt 提 供了 4 种数据类型的输入,可以是一个字符串、一个 int 类型数据、一个 double 类型数据 或者是一个下拉列表框的条目。此外,一般情况下在输入框的附近应该放置一个标签窗口部 件,告诉用户需要输入什么样的值。一个标准输入框的样子如图 7-18 所示。

经常使用的方法有 4 个:getText(),getInt(), getDouble()和 getItem(),它们都 是 QInputDialog 类的静态方法,使用起来也非常简便,请看下面的示例代码。

bool ok;
QString text = QInputDialog::getText(this, tr("User Name"),
    tr("Please input new name"), QLineEdit::Normal,
    QDir::home().dirName(), &ok);
if (ok && !text.isEmpty())
{
    textLabel->setText(text);
}

这段代码将弹出一个对话框请用户输入 "User name"的值,如图 7-18 所示。如果用户按下 OK 按钮,则 ok 的值将为 true,反之将为 false。

图 7-18 标准输入框

7.4.2 标准颜色对话框(QColorDialog)

标准颜色选择对话框被用来为应用程序指定颜色。比如,在一个绘图应用程序中选择 画刷的颜色等。一个典型的标准颜色对话框如图 7-19 所示。

图 7-19 典型的标准颜色对话框

我们经常使用 QColorDialog 类的静态方法 getColor()来创建标准颜色选择对话框。在 其中除了为用户提供了颜色选择面板外,还可以允许用户选择不同的透明度的颜色。

在使用 QColorDialog 类之前,需要引入其头文件声明。

#include <QColorDialog>

getColor()方法有两种原型,第一种如下:

QColor QColorDialog::getColor ( const QColor & initial, QWidget * parent,
    const QString & title,ColorDialogOptions options = 0 ) [static]

该方法以 parent 为父窗体,以 initial 为默认颜色,以 title 为窗口标题(如果不指 定的话,将显示为"Select Color")创建一个模态的颜色对话框,允许用户选择一个字体,并将其返回。如果用户点击了【Cancel】按钮,则返回一个非正常值。这可以通过 bool QColor::isValid () const 方法来校验,如果字体正常则返回值为 ture;反之则返回 false。

另外,通过配置不同的 options 参数能够对颜色对话框的观感进行定制。 options 的取 值来自枚举值 QColorDialog::ColorDialogOption,它也是 Qt4.5 以后引入的,其含义如表 7-2 所示。

表 7-2 枚举值 QColorDialog::ColorDialogOption 的含义

常量说明
QColorDialog::ShowAlphaChannel0x00000001允许用户选择颜色的 alpha 值
QColorDialog::NoButtons0x00000002不显示 OK 和 Cancel 按钮
QColorDialog::DontUseNativeDialog0x00000004使用 Qt 的标准颜色对话框。比如在 Mac OS X 系统中不使用 Apple 的原 生颜色面板

实际中最为常用的是下面这种,它是第一种原型的重载版本。

QColor QColorDialog::getColor ( const QColor & initial =
    Qt::white, QWidget * parent = 0 ) [static]

一个创建标准颜色对话框的示例代码如下:

QColor color = QColorDialog::getColor(Qt::green, this);
if(color.isValid())
{
    colorLabel->setText(color.name());
    colorLabel->setPalette(QPalette(color));
    colorLabel->setAutoFillBackground(true);
}

第 1 句创建标准颜色选择对话框。

第 2 句判断颜色是否有效。

第 3 句设置 colorLabel 显示的文本是用户从标准颜色对话框中选择的颜色的名字。

第 4 句通过 setPalette()方法设置 colorLabel 的调色板信息。setPalette()方法经常用于此 种场合。

第 5 句也很重要,setAutoFillBackground()方法用于设置窗体能够自动填充背景。

7.4.3 标准字体对话框(QFontDialog)

标准字体对话框为用户选择字体提供了便捷的途径。 其常见的情形如图 7-20 所示。

图 7-20 标准字体对话框

通常有两种方式创建字体对话框,一种是使用 QFontDialog 类的构造函数,一种是使用 QFontDialog 类的静态方法 getFont()。在使用 QFontDialog 类之前,应加入其头文件声明:

#include <QFontDialog>

1.构造函数第一种原型

QFontDialog::QFontDialog ( QWidget * parent = 0 )

它将创建一个标准的字体对话框。其中 parent 参数默认即是上下文环境中的父窗口。

这之后可以使用 setCurrentFont()方法来指定初始的字体。该方法是 Qt4.5 以后引进的,一个 示例代码如下:

QFontDialog fontDlg;
fontDlg.setCurrentFont( QFont(“Times”,12) );

2.构造函数第二种原型

QFontDialog::QFontDialog ( const QFont & initial, QWidget * parent = 0 )

它将使用 parent 作为父窗体,使用 initial 作为默认选择的字体来创建一个标准的字体对话框。该方法是 Qt4.5 以后引进的。一个示例代码如下:

QFontDialog fontDlg(QFont(“Times”,12),this);

3.使用静态方法 getFont()

它有 6 种原型,最为常用的是

QFont QFontDialog::getFont ( bool * ok, const QFont & initial, QWidget * parent,
    const QString & title,FontDialogOptions options ) [static]

它创建一个模态的字体选择框,并把用户选择的字体作为返回值。

如果用户点击了【OK】按钮,被用户选择的字体就会被返回。如果用户按下了【Cancel】按钮,那么 initial 将被返回。

它的各个参数的含义是这样的,parent 指定了字体对话框的父窗口,title 是该字体对话 框的标题栏显示的内容,initial 是对话框建立时初始选择的字体。如果 ok 是非空的,当用 户选择了【OK】按钮时,它将被置为 true,当用户选择了【Cancel】按钮时,它将被置为 false。一个示例代码如下:

bool ok;
QFont font = QFontDialog::getFont(&ok, QFont("Times", 12), this);
if (ok)
{
    // font is set to the font the user selected
}
else
{
    // the user canceled the dialog; font is set to the initial
    // value, in this case Times, 12.
}

这段代码调用 getFont()方法时,对 title 和 options 参数使用了默认值。

也可以使用下面示例的代码直接在某个窗口部件内部使用字体对话框。当用户按下【OK】按钮时,被选中的字体将被使用,当用户按下 【Cancel】按钮时,将仍然使用原来 的字体。

myWidget.setFont(QFontDialog::getFont(0, myWidget.font()));

小贴士:在字体对话框运行期间,不要删除 parent 指定的父窗口。如果你想这么做的话,就不要使用 getFont()方法来创建字体对话框,而是使用它的构造函数来实现。

下面一种原型也会经常用到,它同样也是 QFontDialog 类的静态方法:

QFont QFontDialog::getFont ( bool * ok, QWidget * parent = 0 ) [static]

它以 parent 为父窗体创建一个模态的字体对话框,并且返回一个字体。如果用户点击了【OK】按钮,则被选中的字体将被返回,并且 ok 参数将被置成 true;如果用户点击了【Cancel】按钮,则 Qt 默认字体将被返回,ok 参数将被置成 false。

一个创建标准字体对话框的示例代码如下:

bool ok;
QFont font = QFontDialog::getFont(&ok, this);
if (ok)
{
    // font is set to the font the user selected
}
else
{
    // the user canceled the dialog; font is set to the default
    // application font, QApplication::font()
}

这里同样注意,在使用该方法创建的字体对话框运行期间,不要删除其父窗体。

7.4.4 标准消息对话框(QMessageBox)

在程序开发中,经常会遇到各种各样的消息框来给用户一些提示或提醒, Qt 提供了 QMessageBox 类来实现此项功能。在使用 QMessageBox 类之前,应加入其头文件声明:

#include <QMessageBox>

Question 消息框、Information 消息框、Warning 消息框和 Critical 消息框的用法大同小异,这些消息框一般都包含一条提示信息、一个图标以及若干个按钮,它们的作用都是给用 户提供一些提醒或一些简单的询问。按图标的不同可以区分为表 7-3 所示的 4 个级别。

表 7-3 预定义图标的含义

通常有两种方法可以用来创建标准消息对话框。一种是采用 “基于属性的”API,一种是 使用 QMessageBox 的静态方法。这两种方法各有所长,使用静态方法是比较 容易的,但是缺乏灵活性,并且针对用户给出的提示信息不够丰富 ,并且不能自定义消息对话框里面的按钮提示信息。因此,“基于属性的”API 的方法更值得推荐。

1. 基于属性的 API 方法 这种方法的要领如下。

第 1 步,创建一个 QMessageBox 的实例

第 2 步,设置必要的属性信息,通常只需设置 message text 属性即可。 第 3 步,调用 exec()方法显示这个消息框。

下面是一段示例代码。

QMessageBox msgBox;
msgBox.setText(tr("The document has been modified."));
msgBox.exec();

图 7-21 显示一个提示框

这将创建一个提示框,如图 7-21 所示。上面只有一个 OK 按钮,用户必须点击它才能 使该对话框消失,从而结束对话,并且消除模态对话框对交互的阻塞。

2. 使用 QMessageBox 类的静态方法 这种方法使用起来比较简单,一句程序就可以实现,下面 这段示例代码是从下一节中的例子里面来的:

QMessageBox::StandardButton reply;
reply = QMessageBox::critical(this, tr("QMessageBox::critical()"),
    MESSAGE,
    QMessageBox::Abort | QMessageBox::Retry | QMessageBox::Ignore);
if (reply == QMessageBox::Abort)
{
    criticalLabel->setText(tr("Abort"));
}
else if (reply == QMessageBox::Retry)
{
    criticalLabel->setText(tr("Retry"));
}
else
{
    criticalLabel->setText(tr("Ignore"));
}

第 1 句声明一个 QMessageBox::StandardButton 类型变量, QMessageBox::StandardButton 是一个枚举量,它包含了 QMessageBox 类默认提供的按 钮提示信息,如 OK、Help、Yes、No、Abort、Retry、Ignore 等。

第 2 句调用 QMessageBox 的静态方法 QMessageBox::critical()创建一个 critical 类型 的消息对话框,上面一些提示信息和三个按钮,其效果如图 7-22 所示。

图 7-22 使用静态方法创建标准消息对话框

第 3-8 句则是根据用户选择的按钮不同而把返回值赋给对应的标签部件的文本显示。

7.4.5 实例:标准对话框的使用

下面以一个实例来说明上面这些内置对话框的使用方式和它们之间的区别。本实例主要包含了 7 种类型的消息框,包括 Question 消息框、Information 消息框、Warning 消息框、Critical 消息框、About 消息框、About Qt(关于 Qt)消息框以及 Custom(自定义) 消息框。当用户点击各个按钮时,将创建对应的标准对话框,程序的运行效果如图 7-23 所 示。

图 7-23 综合实例运行效果

我们先来看一下 Dialog 类的头文件。

#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
QT_BEGIN_NAMESPACE
class QLabel;
class QGroupBox;
class QErrorMessage;
QT_END_NAMESPACE
class Dialog : public QDialog
{
    Q_OBJECT
public:
    Dialog(QWidget *parent = 0);
private slots:
    void getAge();
    void getStature();
    void getSex();
    void getName();
    void getColor();
    void getFont();
    void getCriticalMessage();
    void getInformationMessage();
    void getQuestionMessage();
    void getWarningMessage();
    void getErrorMessage();
    void getAboutMessage();
    void getAboutQtMessage();
    void getCustomMessage();
private:
    QLabel *nameLabel;
    QLabel *sexLabel;
    QLabel *ageLabel;
    QLabel *statureLabel;
    QLabel *colorLabel;
    QLabel *fontLabel;
    QLabel *criticalLabel;
    QLabel *informationLabel;
    QLabel *questionLabel;
    QLabel *warningLabel;
    QLabel *errorLabel;
    QLabel *aboutLabel;
    QLabel *aboutQtLabel;
    QLabel *customLabel;
    QErrorMessage *errorMessageDialog;
};
#endif

在文件开始处,首先引入了 QDialog 类的声明,然后前置声明程序中用到的 Qt 类。 Dialog 类公有单继承自 QDialog,接下来为其声明若干个私有槽函数和私有成员变量。

小贴士:类的成员变量尽量声明为私有的。

在 Dialog 类的实现文件的最开始处定义一个宏 MESSAGE,它保存了后面 MessageBox 类 的实例用到的提示信息。

#include <QtGui>
#include "dialog.h"
#define MESSAGE \
Dialog::tr("<p>Message boxes have a caption, a text, " \
"and any number of buttons, each with standard or custom texts." \
"<p>Click a button to close the message box. Pressing the Esc button " \
"will activate the detected escape button (if any).")

然后看一下构造函数。


Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
    //! [1]
    setWindowTitle(tr("Standard Dialogs"));
    errorMessageDialog = new QErrorMessage(this);
    int frameStyle = QFrame::Sunken | QFrame::Panel;
    //! [1]
    //! [2]
    //Name
    nameLabel = new QLabel;
    nameLabel->setFrameStyle(frameStyle);
    QPushButton *nameButton = new PushButton(tr("&Name(QInputDialog::getText())"));
    //Sex
    sexLabel = new QLabel;
    sexLabel->setFrameStyle(frameStyle);
    QPushButton *sexButton = new QPushButton(tr("&Sex(QInputDialog::getItem())"));
    //Age
    ageLabel = new QLabel;
    ageLabel->setFrameStyle(frameStyle);
    QPushButton *ageButton = new pushButton(tr("&Age(QInputDialog::getInteger())"));
    //Stature
    statureLabel = new QLabel;
    statureLabel->setFrameStyle(frameStyle);
    QPushButton *statureButton = new
    QPushButton(tr("S&tature(QInputDialog::getDouble())"));
    //setup inputdialog groupbox
    QGroupBox *inputDialogGBox = new QGroupBox(tr("Input Dialog"));
    QGridLayout *inputDialogGridLayout = new QGridLayout;
    inputDialogGridLayout->setColumnStretch(1, 1);
    inputDialogGridLayout->setColumnMinimumWidth(1, 100);
    inputDialogGridLayout->addWidget(nameButton, 0, 0);
    inputDialogGridLayout->addWidget(nameLabel, 0, 1);
    inputDialogGridLayout->addWidget(sexButton, 1, 0);
    inputDialogGridLayout->addWidget(sexLabel, 1, 1);
    inputDialogGridLayout->addWidget(ageButton, 3, 0);
    inputDialogGridLayout->addWidget(ageLabel, 3, 1);
    inputDialogGridLayout->addWidget(statureButton, 4, 0);
    inputDialogGridLayout->addWidget(statureLabel, 4, 1);
    inputDialogGBox->setLayout(inputDialogGridLayout);
    //! [2]
    //! [3]
    //Color
    colorLabel = new QLabel;
    colorLabel->setFrameStyle(frameStyle);
    QPushButton *colorButton = new QPushButton(tr("&Color"));
    //Font
    fontLabel = new QLabel;
    fontLabel->setFrameStyle(frameStyle);
    QPushButton *fontButton = new QPushButton(tr("&Font"));
    //setup color&font Dialog groupbox
    QGroupBox *colorAndFontDlgGBox = new QGroupBox(tr("Color Dialog And Font
    Dialog"));
    QGridLayout *colorAndFontDlgGLayout = new QGridLayout;
    colorAndFontDlgGLayout->setColumnStretch(1, 1);
    colorAndFontDlgGLayout->addWidget(colorButton, 0, 0);
    colorAndFontDlgGLayout->addWidget(colorLabel, 0, 1);
    colorAndFontDlgGLayout->addWidget(fontButton, 1, 0);
    colorAndFontDlgGLayout->addWidget(fontLabel, 1, 1);
    colorAndFontDlgGBox->setLayout(colorAndFontDlgGLayout);
    //! [3]
    //! [4]
    //Question MessageBox
    questionLabel = new QLabel;
    questionLabel->setFrameStyle(frameStyle);
    QPushButton *questionButton = new QPushButton(tr("&Question"));
    //Information MessageBox
    informationLabel = new QLabel;
    informationLabel->setFrameStyle(frameStyle);
    QPushButton *informationButton = new QPushButton(tr("&Information"));
    //Warning MessageBox
    warningLabel = new QLabel;
    warningLabel->setFrameStyle(frameStyle);
    QPushButton *warningButton = new QPushButton(tr("&Warning"));
    //Critical MessageBox
    criticalLabel = new QLabel;
    criticalLabel->setFrameStyle(frameStyle);
    QPushButton *criticalButton = new QPushButton(tr("Critica&l"));
    //Error MessageBox
    errorLabel = new QLabel;
    errorLabel->setFrameStyle(frameStyle);
    QPushButton *errorButton = new QPushButton(tr("Show &Message"));
    //setup messageBox dialog groupbox
    QGroupBox *messageBoxDlgGBox = new QGroupBox(tr("MessageBox Dialog"));
    QGridLayout *messageBoxDlgGLayout = new QGridLayout;
    messageBoxDlgGLayout->setColumnStretch(1, 1);
    messageBoxDlgGLayout->addWidget(questionButton, 0, 0);
    messageBoxDlgGLayout->addWidget(questionLabel, 0, 1);
    messageBoxDlgGLayout->addWidget(informationButton, 1, 0);
    messageBoxDlgGLayout->addWidget(informationLabel, 1, 1);
    messageBoxDlgGLayout->addWidget(warningButton, 2, 0);
    messageBoxDlgGLayout->addWidget(warningLabel, 2, 1);
    messageBoxDlgGLayout->addWidget(criticalButton, 3, 0);
    messageBoxDlgGLayout->addWidget(criticalLabel, 3, 1);
    messageBoxDlgGLayout->addWidget(errorButton, 4, 0);
    messageBoxDlgGLayout->addWidget(errorLabel, 4, 1);
    messageBoxDlgGBox->setLayout(messageBoxDlgGLayout);
    //! [4]
    //! [5]
    //About MessageBox
    aboutLabel = new QLabel;
    aboutLabel->setFrameStyle(frameStyle);
    QPushButton *aboutButton = new QPushButton(tr("A&bout"));
    //AboutQt MessageBox
    aboutQtLabel = new QLabel;
    aboutQtLabel->setFrameStyle(frameStyle);
    QPushButton *aboutQtButton = new QPushButton(tr("Ab&out Qt"));
    //custom MessageBox
    customLabel = new QLabel;
    customLabel->setFrameStyle(frameStyle);
    QPushButton *customButton = new QPushButton(tr("Custom M&essageBox"));
    //setup about dialog groupbox
    QGroupBox *aboutMessageDlgGBox = new QGroupBox(tr("About And Custom MessageBox
    Dialog"));
    QGridLayout *aboutMessageBoxDlgGLayout = new QGridLayout;
    aboutMessageBoxDlgGLayout->setColumnStretch(1, 1);
    aboutMessageBoxDlgGLayout->addWidget(aboutButton, 0, 0);
    aboutMessageBoxDlgGLayout->addWidget(aboutLabel, 0, 1);
    aboutMessageBoxDlgGLayout->addWidget(aboutQtButton, 1, 0);
    aboutMessageBoxDlgGLayout->addWidget(aboutQtLabel, 1, 1);
    aboutMessageBoxDlgGLayout->addWidget(customButton, 2, 0);
    aboutMessageBoxDlgGLayout->addWidget(customLabel, 2, 1);
    aboutMessageDlgGBox->setLayout(aboutMessageBoxDlgGLayout);
    //! [5]
    //! [6]
    //connect signals and slots
    connect(ageButton, SIGNAL(clicked()), this, SLOT(getAge()));
    connect(statureButton, SIGNAL(clicked()), this, SLOT(getStature()));
    connect(sexButton, SIGNAL(clicked()), this, SLOT(getSex()));
    connect(nameButton, SIGNAL(clicked()), this, SLOT(getName()));
    connect(colorButton, SIGNAL(clicked()), this, SLOT(getColor()));
    connect(fontButton, SIGNAL(clicked()), this, SLOT(getFont()));
    connect(criticalButton, SIGNAL(clicked()), this, SLOT(getCriticalMessage()));
    connect(informationButton, SIGNAL(clicked()),this,
    SLOT(getInformationMessage()));
    connect(questionButton, SIGNAL(clicked()), this, SLOT(getQuestionMessage()));
    connect(warningButton, SIGNAL(clicked()), this, SLOT(getWarningMessage()));
    connect(errorButton, SIGNAL(clicked()), this, SLOT(getErrorMessage()));
    connect(aboutButton, SIGNAL(clicked()), this, SLOT(getAboutMessage()));
    connect(aboutQtButton, SIGNAL(clicked()), this, SLOT(getAboutQtMessage()));
    connect(customButton, SIGNAL(clicked()), this, SLOT(getCustomMessage()));
    //! [6]
    //! [7]
    //Setup MainLayout
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(inputDialogGBox);
    mainLayout->addWidget(colorAndFontDlgGBox);
    mainLayout->addWidget(messageBoxDlgGBox);
    mainLayout->addWidget(aboutMessageDlgGBox);
    setLayout(mainLayout);
    //! [7]
}

在代码块[1]中,首先为应用程序设置标题栏,接着定义了一个 QErrorMessage 的实例,然后定义一个 QFrame 类的实例,用作应用程序窗口部件的风格。关于 QFrame,这里重 点讲解一下。

专题:关于 QFrame 类的使用

一般继承自 QWidget 的类都可以设置它的 frame 属性。比如 QLabel 类的窗口在默认情 况下拥有一个平面的(flat)观感,而 QProgressBar 类的窗口则拥有一个向下凹陷(sunken)的观感。当然这些都是可以通过设置它们的 frame 而改变的。下面是一段示意代码,演示了如何设置窗口部件的 frame。

QLabel label(...);
label.setFrameStyle(QFrame::Panel | QFrame::Raised);
label.setLineWidth(2);
QProgressBar pbar(...);
label.setFrameStyle(QFrame::NoFrame);

一个窗口部件的 frame 有两个重要的属性,一个是 shapes,一个是 style。

style 由 QFrame::Shape 和 QFrame::Shadow 枚举值共同来指定,它们可以使设置了 frame 的窗口部件与其他的区分开来。一般可以使用 setFrameStyle()方法来设置 frame 的 属性,而使用 frameStyle()方法来读取该设置。

setFrameStyle()的原型如下:

void QFrame::setFrameStyle ( int style )

它的作用就是设置该窗口部件的 frame 为 style。

常见的各种应用程序的 frame 的观感如图 7-24 所示。

图 7-24 各种 frame 组合起来的效果

在代码块[2]-[5]中,创建了程序中用到的各种窗口部件,然后把它们分类放到几个分 组框中,最后为分组框设置了布局。这其中的重点是 QGroupBox 类的使用,它用作创建分 组框,请看下面的专题讲解。

专题:QGroupBox 类的使用

QGroupBox 为构建分组框提供了支持。分组框通常带有一个边框和一个标题栏,作为容 器部件来使用,在其中可以布置各种窗口部件。分组框的标题通常在上方显示,其位置可以 设置为靠左、居中、靠右、自动调整这几种方式之一。位于分组框之中的窗口部件可以获得 应用程序的焦点。

位于分组框之内的窗口部件被称作是它的子窗口,通常使用 addWidget()方法把子窗口 部件加入到分组框之中。

使用分组框的一般步骤如下:

1. 实例化分组框对象

使用 QGroupBox 构造函数来实例化分组框对象,示例代码如下:

QGroupBox *groupBox = new QGroupBox(tr("Exclusive Radio Buttons"));

2. 创建位于分组框之中的子窗口部件

同样使用该窗口部件的构造函数来实现,示例代码如下:

QRadioButton *radio1 = new QRadioButton(tr("&Radio button 1"));

3. 创建一个布局

这个布局就是后面要设置在分组框之上的布局, Qt 提供的常见布局类型比如水平布 局、垂直布局、栅格布局、表单布局等都可以,目前还不支持分裂器布局。示例代码如下:

QVBoxLayout *vbox = new QVBoxLayout;

4. 把第 2 步创建的子窗口部件加入到第 3 步创建的布局之中

一般使用 addWidget()或者 insertWidget()方法把子窗口部件加入到布局之中。示例 代码如下:

QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(radio1);

5. 把第 3 步创建的布局应用到分组框上

最后,使用 setLayout()方法把布局应用到分组框上,示例代码如下:

groupBox->setLayout(vbox);

注意,创建分组框及其内部的子窗口部件时,以上次序不要改变。当分组框内部没有

子窗口部件时,是无法为其应用布局的。再有就是,要牢固记得 QGroupBox 是 QWidget 的 子类,QWidget 的公有方法,它的对象都可以使用,它本身就是一个窗口部件。最后,一般 情况下,在应用程序中只要使用了分组框,就要为它应用一个布局,请读者朋友注意体会。

下面是一个示例程序片段,它演示了创建分组框并为其设置布局的过程。

QGroupBox *groupBox = new QGroupBox(tr("Exclusive Radio Buttons"));
QRadioButton *radio1 = new QRadioButton(tr("&Radio button 1"));
QRadioButton *radio2 = new QRadioButton(tr("R&adio button 2"));
QRadioButton *radio3 = new QRadioButton(tr("Ra&dio button 3"));
radio1->setChecked(true);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(radio1);
vbox->addWidget(radio2);
vbox->addWidget(radio3);
vbox->addStretch(1);
groupBox->setLayout(vbox);

代码块[6]设置程序中的信号和槽的连接

代码块[7]设置程序总的布局。 接下来看一下设置年龄的函数 getAge()。

void Dialog::getAge()
{
bool ok;
int age = QInputDialog::getInteger(this,tr("User Age"),
tr("Please input age"),ageLabel->text().toInt(),0,150,1,&ok);
if(ok)
{
    ageLabel->setText(QString(tr("%1")).arg(age));
}
}

静态方法 QInputDialog::getInteger 用于创建基于整数的标准输入框。

QString 的 toInt()方法原型如下:

int QString::toInt ( bool * ok = 0, int base = 10 ) const

它的作用是以 base 为基准将字符串转化为整数。如果 base 等于 0,则表示将使用 C 语 言规定的转换方法,即如果字符串是以 0x 开头的,则转换成 16 进制的整数;如果字符串是以 0 开头的,则转换成 8 进制整数,其它情况则转换成 10 进制整数。一般我们使用十进 制整数的时候较多。

再看一下设置性别的函数 getSex()是如何定义的。

void Dialog::getSex()
{
    QStringList items;
    items << tr("male") << tr("female");
    bool ok;
    QString sex = QInputDialog::getItem(this,tr("Sex"),
    tr("Please select sex"),items,0,false,&ok);
    if (ok)
    {
        sexLabel->setText(sex);
    }
}

其中,QStringList 类用于容纳一些列的字符串对象。操作符 <<的原型如下:

QStringList & QStringList::operator&lt;&lt; ( const QString & str )

它的作用于 append()方法相同,将 str 附加到已知的字符串列表中,并返回该列表的引用。

设置字体的函数 getFont()是这样定义的。

void Dialog::getFont()
{
bool ok;
QFont font = QFontDialog::getFont(&ok, QFont(fontLabel-&gt;text()), this);
if (ok)
{
    fontLabel-&gt;setText(font.key());
    fontLabel-&gt;setFont(font);
}
}

第 3 行调用 getFont()方法创建标准字体对话框。

第 5 行设置 fontLabel 的文本是 font 的文本描述。QFont 的 key()方法的原型如下:

QString QFont::key () const

它返回该字体的文本描述代码。

第 6 行设置 fontLabel 的字体为用户选中的 font。 现在看看自定义消息对话框的方法,在 getWarningMessage()方法中有很好的示范。

void Dialog::getWarningMessage()
{
    QMessageBox msgBox(QMessageBox::Warning, tr("QMessageBox::warning()"),
    MESSAGE, 0, this);
    msgBox.addButton(tr("Save &Again"), QMessageBox::AcceptRole);
    msgBox.addButton(tr("&Continue"), QMessageBox::RejectRole);
    if (msgBox.exec() == QMessageBox::AcceptRole)
    {
        warningLabel-&gt;setText(tr("Save Again"));
    }
    else
    {
        warningLabel-&gt;setText(tr("Continue"));
    }
}

首先使用构造函数而不是静态方法创建 QMessageBox 的实例。然后使用 addButton()方法为消息对话框添加按钮。QMessageBox::AcceptRole()和 QMessageBox::RejectRole()是 枚举变量 QMessageBox::ButtonRole 的取值之一,该枚举变量描述了按钮在消息对话框中 的作用。QMessageBox::AcceptRole 表示当用户单击该按钮时,将导致对话框被接受,类似 于 OK 按钮的作用,而 QMessageBox::RejectRole()表示当用户单击该按钮时,将导致对话 框被拒绝,类似于 Cancel 按钮的作用。