1、源代码
#ifndef FINDDIALOG_H
#define FINDDIALOG_H
#include <QDialog>//它是对话框的基类,从QWidget类中派生出来
#include <QCheckBox>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
//接下来是四个类的前置声明
class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;
//接下来定义FindDialog,并让它成为QDialog的子类
class FindDialog: public QDialog
{
Q_OBJECT
//对于所有定义了信号和槽的类,在类定义开始处的Q_OBJECT宏是必须的。
public:
FindDialog(QWidget * parent = 0);
//parent参数指定了它的父窗口部件,该参数为空,意味着该对话框没有父对象
signals:
//当用户单击Find按钮时对话框会发射下面定义的两个信号,signals也是一个宏
void findNext(const QString & str, Qt::CaseSensitivity cs);
void findPrevious(const QString & str, Qt::CaseSensitivity cs);
//Qt::CaseSensitivity是一个枚举类型,它有Qt::CaseSensitive和Qt::CaseInsensitive两个取值
private slots://slots像signal一样也是一个宏
void findClicked();
void enableFindButton(const QString & text);
private:
QLabel *label;
QLineEdit *lineEdit;
QCheckBox *caseCheckBox;
QCheckBox *backwardCheckBox;
QPushButton *findButton;
QPushButton *closeButton;
};
#endif // FINDDIALOG_H
#include "finddialog.h"
#include <QtGui>
#include <QHBoxLayout>
FindDialog::FindDialog(QWidget *parent):QDialog(parent)
//把parent参数传递给了基类的构造函数,然后创建子窗口部件
{
label = new QLabel(tr("Find &what:"));//创建了一个带有快捷键(Alt+W)的标签
lineEdit = new QLineEdit;
label->setBuddy(lineEdit);//设置了行编辑器作为标签的伙伴。伙伴就是一个窗口部件。
caseCheckBox = new QCheckBox(tr("Math &case"));
backwardCheckBox = new QCheckBox(tr("Search &backward"));
findButton = new QPushButton(tr("&Find"));//创建了一个Find按钮,用户
findButton->setDefault(true);//让Find按钮称为对话框的默认按钮
findButton->setEnabled(false);//禁用了Find按钮,当禁用一个部件时,它会显示为灰色
/*
findButton = new QPushButton(tr("&Find"));//创建了一个Find按钮
用户可在那些支持快捷键的平台下通过按下Alt+F来激活它。符号&可以用来控制焦点。
*/
closeButton = new QPushButton(tr("Close"));
connect(lineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(enableFindButton(const QString &)));
connect(findButton, SIGNAL(clicked()), this, SLOT(findClicked()));
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
/*
1、当行编辑器中的文本发生了变化,就会调用私有槽enableFindButton(const QString &)
2、当用户单击Find按钮时,会调用findclicked()私有槽。
3、当用户单击close时,对话框会关闭。
因为QObject是FindDialog的父对象之一,所以省略了connec()函数前面的QObject::前缀
*/
QHBoxLayout *topLeftLayout = new QHBoxLayout;
topLeftLayout->addWidget(label);
topLeftLayout->addWidget(lineEdit);
QVBoxLayout *leftLayout = new QVBoxLayout;
leftLayout->addLayout(topLeftLayout);//子布局对象添加到父布局对象中
leftLayout->addWidget(caseCheckBox);
leftLayout->addWidget(backwardCheckBox);
QVBoxLayout *rightLayout = new QVBoxLayout;
rightLayout->addWidget(findButton);
rightLayout->addWidget(closeButton);
rightLayout->addStretch();
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftLayout);//子布局对象添加到父布局对象中
mainLayout->addLayout(rightLayout);//子布局对象添加到父布局对象中
setLayout(mainLayout);//主布局装到对话框中
/*
setLayout(mainLayout);执行完这一句,也就是主布局装到对话框中去时,它会成为
对话框的子对象,于是所有的子窗口部件都会重定义自己的父对象,从而变成对话框中的子对象。
leftLayout->addLayout(topLeftLayout);
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout);
当将子布局对象添加到父布局对象中时,子布局对象就会自动重定义自己的父对象。
*/
setWindowTitle(tr("Find"));
setFixedHeight(sizeHint().height());
/*
设置了显示在对话框标题栏上的标题的内容,并让窗口具有一个固定的高度,这是因为在
对话框的垂直方向上再没有其他窗口部件可以去占用所多出的空间了。
QWidget::sizeHint()函数可以返回一个窗口部件所理想的尺寸大小。
*/
}
void FindDialog::findClicked()
{
QString text = lineEdit->text();
Qt::CaseSensitivity cs = caseCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive;
if(backwardCheckBox->isChecked())
{
emit findPrevious(text, cs);
}
else
{
emit findNext(text, cs);
}
}
void FindDialog::enableFindButton(const QString &text)
{
findButton->setEnabled(!text.isEmpty());
}
#include <QApplication>
#include "finddialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FindDialog *dialog = new FindDialog;
dialog->show();
return a.exec();
}

2、运行结果:
Qt——查找对话框实例
3、深入介绍信号和槽
槽和信号连接在一起,每当发射一个信号的时候,就会自动调用这个槽。连接语句如下:
connect(sender, SIGNAL(signal),receiver,SLOT(slot));
其中,sender和receiver是对象的指针,signal和slot是不带参数的函数。
- 一个信号可以连接多个槽
connect(slider, SIGNAL(valueChanged(int)),spinBox,SLOT(setValue(int)));
connect(slider, SIGNAL(valueChanged(int)),this,SLOT(updateStatusBar(int)));
- 多个信号连接同一个槽
connect(lcd, SIGNAL(overflow()),this,SLOT(handleMathError()));
connect(calculator, SIGNAL(divisionByZero()),this,SLOT(handleMathError()));
- 一个信号与另一个信号连接
connect(lineEdit, SIGNAL(textChanged(const QString &)),this,SLOT(updateRecord(const QString &)));
- 连接可以被拆除
disconnect(lcd, SIGNAL(overflow()),this,SLOT(handleMathError()));
这个情况用的比较少,因为当删除对象时,Qt会自动移除和这个对象相关的所有连接。