引文
转载请保留出处
改定履历
2011-08-07----------------------------------新建文本文档
一、
新建一个工程,选择QT Application,工程名qtFindDlg;注意,BaseDialog选择QDialog,而不是默认的QMainWindow;点击“完成”。
程序完成运行效果如图:
上代码finddlg.h:
#ifndef FINDDLG_H
#define FINDDLG_H
#include <QtGui/QDialog>
#include "ui_finddlg.h"
class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;
class FindDlg : public QDialog
{
Q_OBJECT
public:
FindDlg(QWidget *parent = 0, Qt::WFlags flags = 0);
~FindDlg();
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:
Ui::FindDlgClass ui;
QLabel* m_pQLabel;
QLineEdit* m_pQLineEdit;
QCheckBox* m_pQCaseCheckBox;
QCheckBox* m_pQBackwardCheckBox;
QPushButton* m_pQFindButton;
QPushButton* m_pQCloseButton;
};
#endif // FINDDLG_H
对于所有定义了信号和槽的类,在类定义开始处的Q_OBJECT宏都是必需的。
Signals部分声明了当用户单击Find按钮时对话框所发射的信号。
Signals关键字实际上是一个宏。C++预处理器会在编译程序找到它之前把它转换成标准C++代码。
之后private slots:声明了两个槽。为了实现这两个槽,几乎需要访问这个对话框的所有子窗口部件(控件),所以也就保留了指向这些子窗口部件的指针。关键字slots如同signals一样也是一个宏。
下面是finddlg.cpp的代码
#include <QtGui>
#include "finddlg.h"
#include <iostream>
#include <exception>
FindDlg::FindDlg(QWidget *parent, Qt::WFlags flags)
: QDialog(parent, flags)
{
ui.setupUi(this);
try
{
m_pQLabel = new QLabel(tr("Find &what:"));
m_pQLineEdit = new QLineEdit;
m_pQLabel->setBuddy(m_pQLineEdit);
m_pQCaseCheckBox = new QCheckBox(tr("Match &case"));
m_pQBackwardCheckBox = new QCheckBox(tr("Search &backford"));
m_pQFindButton = new QPushButton(tr("&Find"));
m_pQFindButton->setDefault(true);
m_pQFindButton->setEnabled(false);
m_pQCloseButton = new QPushButton(tr("Cl&ose"));
connect(m_pQLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(enableFindButton(const QString&)));
connect(m_pQFindButton, SIGNAL(clicked()), this, SLOT(findClicked()));
connect(m_pQCloseButton, SIGNAL(clicked()), this, SLOT(close()));
QHBoxLayout *topLeftLayout = new QHBoxLayout;
topLeftLayout->addWidget(m_pQLabel);
topLeftLayout->addWidget(m_pQLineEdit);
QVBoxLayout *leftLayout = new QVBoxLayout;
leftLayout->addLayout(topLeftLayout);
leftLayout->addWidget(m_pQCaseCheckBox);
leftLayout->addWidget(m_pQBackwardCheckBox);
QVBoxLayout *rightLayout = new QVBoxLayout;
rightLayout->addWidget(m_pQFindButton);
rightLayout->addWidget(m_pQCloseButton);
rightLayout->addStretch();
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout);
setLayout(mainLayout);
setWindowTitle(tr("Find"));
setFixedHeight(sizeHint().height());
}
catch(std::bad_alloc& e)
{
std::cerr << e.what() << std::endl;
}
catch(...)
{
std::cerr << "err" << std::endl;
}
}
FindDlg::~FindDlg()
{
if (NULL != m_pQLabel)
{
delete m_pQLabel;
}
if (NULL != m_pQLineEdit)
{
delete m_pQLineEdit;
}
if (NULL != m_pQCaseCheckBox)
{
delete m_pQCaseCheckBox;
}
if (NULL != m_pQBackwardCheckBox)
{
delete m_pQBackwardCheckBox;
}
if (NULL != m_pQFindButton)
{
delete m_pQFindButton;
}
if (NULL != m_pQCloseButton)
{
delete m_pQCloseButton;
}
}
void FindDlg::findClicked()
{
QString text = m_pQLineEdit->text();
Qt::CaseSensitivity cs = m_pQCaseCheckBox->isChecked() ? Qt::CaseInsensitive : Qt::CaseInsensitive;
if (m_pQBackwardCheckBox->isChecked())
{
emit findPrevious(text, cs);
}
else
{
emit findNext(text, cs);
}
return;
}
void FindDlg::enableFindButton(const QString& text)
{
m_pQFindButton->setEnabled(!text.isEmpty());
return;
}
代码第X行,“12”符号来表示快捷键,可以用来控制焦点。而在第14行设置了行编辑器作为标签的伙伴。所谓伙伴“buddy”,就是一个窗口部件,它可以在按下标签的快捷键时接收焦点。
通过setDefault(true)让Find按钮成为对话框的默认按钮。意为当用户按下Enter键时如同鼠标点击了“Find”按钮。
当用户单击Find按钮时,就会调用findClicked()槽。而该槽将会发射findPrevious()或findNext()信号。emit是Qt中的关键字,像其他QT扩展一样它也会被C++预处理器转换成标准的C++代码。
由于在创建这个对话框中的窗口部件和而已时使用的是new,所以需要写一个能调用delete的析构函数,以便可以删除所创建的每一个窗口部件和布局。但是这样做并不是必需的,因为QT会在删除父对象的时候自动删除其所属的子对象,也就会删除FindDialog中作为期子孙的所有子窗口部件和子布局。但是个人还是比较喜欢自己控制的东西。