对话框,之所以被成为对话框,是因为它们为用户和应用程序之间提供了一种可以相互“交谈”的交互方式。
绝大多数的图形用户界面应用程序都带有一个有菜单栏、工具栏构成的主窗口以及几十个对主窗口进行补充的对话框。
手写一个对话框;
对话框上控件的生成和布局可以使用代码生成也可以使用设计师模式下的UI来生成;
代码实现控件布局-查找对话框
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 // FINDDIALOG_H
finddialog.cpp
#include "finddialog.h"
#include <QLabel>
#include <QLineEdit>
#include <QCheckBox>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
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"));
QObject::connect(lineEdit,SIGNAL(textChanged(QString)),this,SLOT(enableFindButton(QString)));
QObject::connect(findButton,SIGNAL(clicked()),this,SLOT(findClicked()));
QObject::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());
}
快速设计对话框
Qt的设计初衷就是为了能够直观并且友好的进行手工编码。使用可视化方式会比手工编码显得更自然、更快速,并且也希望能够通过可视化,对那些手工编码所设计的窗体,进行更快速、更容易的测试和修改。
Qt设计师(Qt Designer)提供一种可视化的设计能力。使用Qt设计师所创建的窗体最终仍旧是C++代码。
无论是使用手工编码还是使用Qt设计师,在创建对话框时总是要包含以下这几个相同的基本步骤:
1.创建并初始化子窗口部件。
2.把子窗口部件放到布局中。
3.设置Tab键顺序。
4.建立信号-槽之间的连接。
5.实现对话框中的自定义槽。
具体步骤:
1.拖入一个Label标签,设置objectName属性为“label”,text属性设置为“&Cell Location”;
2.拖入一个lineEdit行编辑器,设置objectName属性为“lineEdit”;
3.拖入第一个按钮PushButton,设置objectName属性为“okButton”,设置enable属性为“false”,设置text属性为“OK”,设置default属性为“true”;
4.拖入第二个按钮PushButton,设置objectName属性为“cancelButton”,设置text属性为“GoToCellDialog”,设置windowTitle属性为“Go to Cell”。
对控件进行布局。
1.选择label标签和lineEdit行编辑器两个控件,生成水平布局HorizonLayout;
2.选择分隔符和两个按钮,同样生成水平布局HorizonLayout;
3.在窗体上,右键菜单中“布局”选择“垂直布局”和“调整大小”,窗体会自动调整到一个合适的长宽尺寸。
使用“Edit Tab Order”设置焦点顺序,在活动控件上,按照希望的顺序依次点击每个控件,就会出现从1开始的焦点顺序。
在Label中设置的“&”是一种快捷键,在“Edit Buddies”设置窗口部件伙伴(buddy)后,显示就不会再出现“&”符
号,会把行编辑器看成是label标签的伙伴。
对项目进行构建后,用户界面编译器(user interface compiler,uic)将gotocelldialog.ui文件转换成C++并且将转换结果存储在ui_gotocelldialog.h文件中。
之前UI实现的界面上的控件创建和信号槽连接,需要另外实现功能代码就需要另外使用继承QDialog类和依赖UI生成的类,来实现缺失的业务功能的代码逻辑。
在构造函数中,调用setupUi()函数来初始化窗体。由于Ui::GoToCellDialog中的成员对象都会public类型,所以可以直接访问Ui::GoToCellDialog中的成员对象;setupUi()函数会自动将那些符合on_objectName_signalName()命名惯例的任意槽与相应的objectName和signalName()信号连接到一起。
connect(lineEdit,SIGNAL(textChanged(const QString&)),this,SLOT(on_lineEdit_textChanged()));
gotocelldialog.cpp
#include "gotocelldialog.h"
#include "ui_gotocelldialog.h"
#include <QRegularExpressionValidator>
#include <QRegularExpression>
GoToCellDialog::GoToCellDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::GoToCellDialog)
{
ui->setupUi(this);
QRegularExpression regExp("[A-Za-z][1-9][0-9]{0,2}");
ui->lineEdit->setValidator(new QRegularExpressionValidator(regExp,this));
QObject::connect(ui->okButton,SIGNAL(clicked()),this,SLOT(accpet()));
QObject::connect(ui->cancelButton,SIGNAL(clicked()),this,SLOT(reject()));
}
GoToCellDialog::~GoToCellDialog()
{
delete ui;
}
void GoToCellDialog::on_lineEdit_textChanged(const QString &arg1)
{
ui->okButton->setEnabled(ui->lineEdit->hasAcceptableInput());
}