Qt4读书笔记5

Qt4读书笔记5

第二章 创建对话框

本章将教你如何用Qt创建对话框。对话框呈献给用户一些选项(options and choices),运行用户设置这些选项。这就叫对话框(dialog boxes,or simply "dialogs"),它提供了用户和应用互相交谈的方式。

许多GUI应用包括一个主窗口(a main window)和一个菜单,一个工具条,还有成打的对话框。当然也可以做一个只有对话框的应用,如计算器。

我们将创建一个纯粹的对话框。然后看看如何使用Qt Designer创建对话框。使用Qt Designer比手工编码如影并易于修改。

QDialogde的子类

源代码分为两个文件:finddialog.hfinddialog.cpp,我们先看看finddialog.h

#ifndef FINDDIALOG_H

#define FINDDIALOG_H

保护头文件,避免多次包含

 

#include <QDialog>

QDialog类继承自QWidge

 

class QCheckBox;

class QLabel;

class QLineEdit;

class QPushButton;

声明后面用到的Qt类。forward declarationC++的惯用做法。

 

然后我们定义了FindDialog作为QDialog的子类

class FindDialog : public QDialog

{

       Q_OBJECT

 

public:

       FindDialog(QWidget *parent = 0);

 

Q_OBJECT宏必须定义在类的开始处,这是使用signals or slot的要求。

FindDialog构造方法是典型的,parent参数指明其父控件。缺省为null,表示这个对话框无父控件。

 

signals:

       void findNext(const QString &str, Qt::CaseSensitivity cs);

       void findPrevious(const QString &str, Qt::CaseSensitivity cs);

signals区域声明两个signal,当用户点击find button时,对话框发出这两个signal.如果search backward选项enabled,对话框发出findPrevious(),否则发出findNext().

signals关键字实际是一个宏。C++预处理器会将其转换成标准C++. Qt::CaseSensitivity是一个enum类型,有两个值:Qt::CaseSensitiveQt::CaseInsensitive

 

private slots:

       void findClicked();

       void enableFindButton(const QString &text);

 

private:

       QLabel *label;

       QLineEdit *lineEdit;

       QCheckBox *caseCheckBox;

       QCheckBox *backwardCheckBox;

       QPushButton *findButton;

       QPushButton *closeButton;

};

 

#endif

 

定义了两个slot.slots也是一个宏

 

下面我们看看finddialog.cpp,这个文件是FindDialog类的实现

#include <QtGui>

#include "finddialog.h"

 

首先包含<QtGui>,这个头文件包括Qt GUI类的定义。Qt包含许多模块,每个模块都有自己的library。最重要的模块是QtCore, QtGui,QtNetwork, QtOpenGL, QtScript, QtSql, QtSvg, QtXml. <QtGui>头文件包括QtCoreQtGui模块所有的类。这样避免了我们自己去找包含的类,减少麻烦。

 

FindDialg::FindDialog(QWidget *parent) : QDialog(parent)

{

       label = new QLabel(tr("Find &what:"));

       lineEdit = new QLineEdit;

       label->setBuddy(lineEdit);

 

       caseCheckBox = new QCheckBox(tr("Match &case"));

       backwardCheckBox = new QCheckBox(tr("Search &backward"));

 

       findButton = new QPushButton(tr("&Find"));

       findButton->setDefault(true);

       findButton->setEnabled(false);

 

       closeButton = new QPushButton(tr("Close"));

其中的tr() function是为了翻译成其他语言做准备。&用于标识快捷键。

label->setBuddy(lineEdit);设置伙伴。当alt+w快键按下时,焦点将转移到lineEdit控件上。

 

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()));

 

private slot enableFindButton(const QString &)line editor的文本改变时被调用。private findClicked()当用户点击Find按钮时被调用。close() slot继承自QWidget,缺省的行为是隐藏widget但不删除。(这与java类似)

 

因为QObjectFindDialog的祖先,我们可以省略connect()调用中的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);

使用布局管理器。布局管理器可以包含widget或者其他布局管理器。通过嵌套使用QHBoxLayout,QVBoxLayoutQGridLayout可以生成很复杂的对话框。

其中addStrech()是在下面增加了spacer item(or stretch).这样可以保证上面的两个按钮在顶部。

 

setWindowTitle(tr("Find"));

setFixedHeight(sizeHint().height());

}

QWidget::sizeHint()函数返回一个widget的实际大小。

 

我们创建了很多对象,没有写相关的delete,只是不需要的,因为当父对象destroyed,Qt自动删除子对象.

 

下面看看dialog's slots:

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());

}

其中的emitqt的关键字,预处理器会将其变成C++代码。

最后是main.cpp来测试FindDialog控件

#include <QApplication>

#include "finddialog.h"

 

int main(int argc, char *argv[])

{

       QApplication app(argc, argv);

       FindDialog *dialog = new FindDialog;

       dialog->show();

       return app.exec();

}

编译问题:

由于使用了Q_OBJECT宏,所以qmake将包含特殊的规则来运行moc(Qt's meta-object compiler)

使用Q_OBJECT宏的类必须有moc运行。qmake会自动增加这些规则到makefile.

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值