Qt(二)自定义窗口一个查找的功能的实现

【Ctrl + F窗口】

finddialog.h:

#ifndef FINDDIALOG_H
#define FINDDIALOG_H

#include <QDialog>

class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;

class FindDialog : public QDialog
{
    Q_OBJECT

public:
    FindDialog(QWidget *parent = 0);

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

private slots:
    void findClicked();
    void enableFindButton(const QString &text);

private:
    QLabel *label;
    QLineEdit *lineEdit;
    QCheckBox *caseCheckBox;
    QCheckBox *backwardCheckBox;
    QPushButton *findButton;
    QPushButton *closeButton;
};

#endif

第6行到第8行声明了一些用于这个对话框实现中的Qt类。前置声明会告诉C++编译程序类的存在,而不用提供类定义中的所有细节。

自定义类FindDialog 让他成为QDialog的子类:

对于所有定义了信号和槽的类,在类定义开始处的Q_OBJECT是必要的。

构造函数 parent指定了它的父窗口部件,如果为0证明它没有父窗口。

Qt::CaseSensitivity 是一个枚举,它有Qt::CaseSensitive 和 Qt::CaseInsensitive俩个取值。

signals 关键字本质是一个宏。

没有必要在头文件中就去访问(如<QCheckBox><QLabel>),

只是前置声明,可以提高编译过程的速度。

#include <QtGui>

#include "finddialog.h"

FindDialog::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"));

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

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

    setWindowTitle(tr("Find"));
    setFixedHeight(sizeHint().height());
}

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

包含<QtGui>该头文件包含了Qt GUI类的定义。

类似的模块还有QtCore,QtGui,QtNetwork,QtOpenGL,QtScript,QtSql,QtXML

其中在<QtGui>中构成了QtCore和QtGui组成部分的所有类进行了定义。

包含这个头文件就能够省去我们在每个类中分别包含的麻烦。

意思就是说,就头文件中包含一个<QtGui>即可,不用每次都包含<QCheckBox>等。但是在头文件包含一个<QtGui>那么大的头文件是一种不好的编程风格。

在字符串周围的tr()函数调用是把它们翻译成其他语言的标记。在每个QObject对象以及包含有Q_OBJECT宏的子类中都有这个函数的声明。尽管我们不去使用翻译这个功能,但是这还是一个不错的习惯呢。

在字符串中使用了 "&"符号来表示快捷键。例如,第11行创建了一个Find按钮,用户可以在支持快捷键的平台下使用Alt+F快捷键激活它。

label->setBuddy(lineEdit):设置了行编辑器作为标签的伙伴。。。就是它可以再按下标签的快捷键时接受焦点。

setDefault(true)让Find按钮成为对话框的默认按钮。意义就是按下enter键时能够按下对应的按钮。

setEnabled(false)禁用了按钮,使按钮变为不可用状态。

由于QObject是FindDialog的父对象之一,所有可以省略connect()函数前面的QObject::前缀。

布局管理控件,那里的代码比较好理解,addStretch主要是为了能很好的占据它本来应该占有的区域。

sizeHint().height();可以返回一个窗口部件所理想的大小。

不需要再析构函数处delete来释放内存控件,因为Qt在删除父对象的时候自动删除其所属的所有子对象,也就会删除FindDialog中作为其子孙的所有子窗口部件和子布局。

猜你喜欢

转载自blog.csdn.net/qq_42418668/article/details/89460079