QT学习笔记2:创建对话框

时间:2022-12-26 11:55:53

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

程序输出:

QT学习笔记2:创建对话框

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中绘制如下图:

QT学习笔记2:创建对话框

2) 保存,(在构建里面,5.3版本的QT creator直接可以淘汰QT designer),这时候会生成

#include "ui_dialog.h"

但是具体的路径不是在当前目录下,鼠标放在上面就知道路径在哪里了。为了方便,我添加了这个路径:

QT学习笔记2:创建对话框

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


dialog.cpp:

#include "dialog.h"
#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;
}
 main.cpp:

#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) 效果图如下:

QT学习笔记2:创建对话框


4. 改变形状的对话框

1) 效果图

未点击more之前(没进行界面大小的配置)和点击more之后:
QT学习笔记2:创建对话框QT学习笔记2:创建对话框

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