1. 手动创建对话框
1) finddialog.h头文件:
#ifndef FINDDIALOG_H
#define FINDDIALOG_H
#include <QDialog.h>
#include <qlabel.h>
#include <qcheckbox.h>
#include <qlineedit.h>
#include <qpushbutton.h>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QMessageBox>
class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;
class FindDialog:public QDialog
{
//对于所有定义了信号和槽的类,在类定义开始处的Q_OBJECT宏都是必需的
Q_OBJECT
public:
FindDialog(QWidget *parent = 0);
public:
void myfindNext(const QString &str, Qt::CaseSensitivity cs);
void myfindPrevious(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
2)finddialog.cpp源文件
#include "finddialog.h"
FindDialog::FindDialog(QWidget *parent) :
QDialog(parent)
{
//在字符串周围的tr()函数调用是把它们翻译成其他语言的标记(这是一个好习惯)
label = new QLabel( tr( "Find &what" ) );
lineEdit = new QLineEdit;
//标签伙伴:一个窗口部件,当你按下Alt+w时,焦点就会移动到这个行编辑器(该标签的伙伴)上
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" ) );
//当文本改变时候,使find按钮有效
connect( lineEdit, SIGNAL( textChanged( const QString & ) ),
this, SLOT( enableFindButton( const QString & ) ) );
//当find按钮按下时候,处罚findClicked函数
connect( findButton, SIGNAL( clicked() ),
this, SLOT( findClicked() ) );
//当close按钮按下时候,出发close函数
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 myfindPrevious( text, cs ); //发射信号
} else {
emit myfindNext( text, cs ); //发射信号
}
}
void FindDialog::enableFindButton( const QString &text )
{
findButton->setEnabled( !text.isEmpty() );
}
void FindDialog::myfindNext(const QString &str, Qt::CaseSensitivity cs)
{
if ( cs == Qt::CaseSensitive ){
QMessageBox::about( this, tr( "提示信息" ), tr( "向前搜索字符串:" ) + str + tr( "。并且大小写敏感!" ) );
}
else{
QMessageBox::about( this, tr( "提示信息" ), tr( "向前搜索字符串:" ) + str + tr( "。并且大小写不敏感!" ) );
}
}
void FindDialog::myfindPrevious(const QString &str, Qt::CaseSensitivity cs)
{
if ( cs == Qt::CaseSensitive ){
QMessageBox::about( this, tr( "提示信息" ), tr( "向后搜索字符串:" ) + str + tr( "。并且大小写敏感!" ) );
}
else{
QMessageBox::about( this, tr( "提示信息" ), tr( "向后搜索字符串:" ) + str + tr( "。并且大小写不敏感!" ) );
}
}
3)main.cpp主文件
#include "finddialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FindDialog *dialog = new FindDialog;
dialog->show();
return a.exec();
}
程序输出:
2. 深入介绍信号和槽
connect()语句通常如下:
connect( sender, SIGNAL( signal ), receiver, SLOT( slot ) );这里的sender和receiver是指向QObject的指针,signal和slot是不带参数的函数名。
1) 一个信号可以连接多个槽
connect( slider, SIGNAL( valueChanged( int ) ), spinBox, SLOT( setValue( int ) ) );在发射这个信号的时候,会以不确定的顺序一个接一个的调用这些槽。
connect( slider, SIGNAL( valueChanged( int ) ), this, SLOT( updateStatusBarIndicator( int ) ) );
2) 多个信号可以连接同一个槽
connect( lcd, SIGNAL( overflow() ), this, SLOT( handleMatchError() ) );无论发射的是哪一个信号,都会调用这个槽。
connect( calculator, SIGNAL( divisionByZero() ), this, SLOT( handleMatchError() ) );
3) 一个信号可以与另外一个信号相连接(这和多个信号连接同一个槽,似乎没什么区别)
connect( lineEdit, SIGNAL( textChanged( const QString & ) ), this, SIGNAL( updateRecord( const QString & ) ) );当发射第一个信号时,也会发射第二个信号。除此之外,信号与信号之间的连接和信号与槽之间的连接是难以区分的。
4) 连接可以被移除
disconnect( lcd, SIGNAL( overflow() ), this, SLOT( handleMatchError() ) );这种情况较少用到,因为当删除对象时,Qt会自动移除和这个对象相关的所有连接。
要把信号成功连接到槽(或者连接到另外一个信号),它们的参数必须具有相同的顺序和相同的类型(毕竟这些参数要从信号传递到槽,或者传递到另外一个信号)。
3. 快速设计对话框
1) 直接打开QT Creator,新建一个对话框dialog即可,在dialog.ui中绘制如下图:
2) 保存,(在构建里面,5.3版本的QT creator直接可以淘汰QT designer),这时候会生成
#include "ui_dialog.h"
但是具体的路径不是在当前目录下,鼠标放在上面就知道路径在哪里了。为了方便,我添加了这个路径:
3) 在dialog.h和dialog.cpp中开始编写系列的信号处理函数(打开ui_dialog.h,就会明白我们刚才绘制的按钮等,均实现在ui_dialog.h中)
dialog.h:
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
private slots:
void on_lineEdit_textChanged( const QString & ); //我们增加的函数
};
#endif // DIALOG_H
#include "dialog.h"main.cpp:
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
QRegExp regExp( "[A-Za-z][1-9][0-9]{0,2}" );
ui->lineEdit->setValidator( new QRegExpValidator( regExp, this ) );
connect( ui->lineEdit, SIGNAL( textChanged( const QString & ) ), this, SLOT( on_lineEdit_textChanged( const QString & ) ) );
connect( ui->okButton, SIGNAL( clicked() ), this, SLOT( accept() ) );
connect( ui->cancelButton, SIGNAL( clicked() ), this, SLOT( reject() ) );
}
void Dialog::on_lineEdit_textChanged( const QString &text )
{
ui->okButton->setEnabled( ui->lineEdit->hasAcceptableInput() );
}
Dialog::~Dialog()
{
delete ui;
}
#include "dialog.h"
#include <QApplication>
#include "gotocelldialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog *dialog = new Dialog;
dialog->show();
return a.exec();
}
4) 效果图如下:
4. 改变形状的对话框
1) 效果图
未点击more之前(没进行界面大小的配置)和点击more之后:
2) 主要代码:
dialog.cpp:
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
ui->groupBox_2->hide();
ui->groupBox_3->hide();
// this->layout()->setSizeConstraint( QLayout::SetFixedSize );
connect( ui->moreButton, SIGNAL( clicked() ), this, SLOT( showGroupBox2() ) );
connect( ui->moreButton, SIGNAL( clicked() ), this, SLOT( showGroupBox3() ) );
setColumnRange( 'A','Z' );
}
void Dialog::showGroupBox2()
{
ui->groupBox_2->show();
}
void Dialog::showGroupBox3()
{
ui->groupBox_3->show();
}
void Dialog::setColumnRange(QChar first, QChar last)
{
ui->comboBox->clear();
ui->comboBox_3->clear();
ui->comboBox_5->clear();
ui->comboBox_3->addItem( tr( "None" ) );
ui->comboBox_5->addItem( tr( "None" ) );
ui->comboBox->setMinimumSize( ui->comboBox_3->sizeHint() );
QChar ch = first;
while ( ch <= last ){
ui->comboBox->addItem( QString( ch ) );
ui->comboBox_3->addItem( QString( ch ) );
ui->comboBox_5->addItem( QString( ch ) );
ch = ch.unicode() + 1;
}
}
Dialog::~Dialog()
{
delete ui;
}