笔记2之Qt4自定义对话框

时间:2022-12-26 12:13:28

QDialog是所有Qt对话框窗口的基类,它继承自QWidget。

用qt creator建立一个名为mydialog的empty qt project工程,并且分别建立logindlg.h、logindlg.cpp、mydialog.cpp文件。

logindlg.h

//定义宏变量,确保该头文件只被包含一次,防止头文件被多次包含
#ifndef LOGINDLG_H
#define LOGINDLG_H

#include<QtGui/QDialog>
#include<QtGui/QLabel>
#include<QtGui/QPushButton>
#include<QtGui/QGridLayout>
#include<QtGui/QHBoxLayout>
#include<QtGui/QVBoxLayout>

class QLineEdit;
class CLoginDlg:public QDialog
{
    Q_OBJECT
public:
    CLoginDlg(QWidget *parent=0);
public slots:
    virtual void accept();
private:
    QLabel *usrLabel;
    QLabel *pwdLabel;

    QLineEdit* usrLineEdit;
    QLineEdit* pwdLineEdit;

    QPushButton *okBtn;
    QPushButton *cancelBtn;

    QHBoxLayout *btnLayout;
    QGridLayout *gridLayout;
    QVBoxLayout *dlgLayout;


};



#endif // LOGINDLG_H)
注:

1、CLoginDlg(QWidget *parent=0)是构造函数,它指定了一个默认值为NULL的指向QWidget的参数。该形参定义了自定义对话框对象的父窗口部件,默认值NULL意味着自定义的对话框没有父窗口部件。
2、代码 “class QLineEdit“是类QLineEdit的传递声明,因为在类CLoginDlg 的头文件中仅仅使用了指向QLineEdit对象的指针,该代码的作用是告诉编译器,QLineEdit类已经存在。这样做的好处减少了头文件的大小,增加了编译速度 (特别是当该头文件被其他文件多次包含引用时),而且可以避免因包含头文件的顺序不当而造成连接错误,特别是在大的工程当中更应该避免随意地在一个头文件中包含另一个头文件。

3、在这里我重新声明了基类QDialog类的虚函数accept()。在类CLoginDlg的实现文件logindlg.cpp中,将重写该函数,目的是为了验证用户输入的用户名和密码的有效性。


logindlg.cpp

#include<QtGui/QtGui>
#include"logindlg.h"

CLoginDlg::CLoginDlg(QWidget* parent):QDialog(parent)
{
    usrLabel=new QLabel(tr("用户名:"));
    pwdLabel=new QLabel(tr("密 码:"));
    usrLineEdit=new QLineEdit;
    pwdLineEdit=new QLineEdit;
    //设置密码编辑框对象pwdLineEdit的内容显示方式为采用星号“*”代替用户输入的字符
    pwdLineEdit->setEchoMode(QLineEdit::Password);

    //创建一个网格布局管理器对象,并将窗口部件添加到该布局管理器中
    gridLayout=new QGridLayout;
    gridLayout->addWidget(usrLabel,0,0,1,1);
    gridLayout->addWidget(usrLineEdit,0,1,1,3);
    gridLayout->addWidget(pwdLabel,1,0,1,1);
    gridLayout->addWidget(pwdLineEdit,1,1,1,3);

    //创建两个按钮对象和一个水平布局管理器对象,并将按钮对象添加到该布局管理器中
    okBtn=new QPushButton(tr("确定"));
    cancelBtn=new QPushButton(tr("取消"));
    btnLayout=new QHBoxLayout;
    btnLayout->setSpacing(60);
    btnLayout->addWidget(okBtn);
    btnLayout->addWidget(cancelBtn);

    //创建一个垂直布局管理器对象,并将水平和网格布局管理器添加到该管理器中
    dlgLayout=new QVBoxLayout;
    dlgLayout->setMargin(40);
    dlgLayout->addLayout(gridLayout);
    dlgLayout->addStretch(40);
    dlgLayout->addLayout(btnLayout);
    setLayout(dlgLayout);

    //将两个按钮的信号与槽关联起来
    connect(okBtn,SIGNAL(clicked()),this,SLOT(accept()));
    connect(cancelBtn,SIGNAL(clicked()),this,SLOT(reject()));

    //设置对话框的标题和大小
    setWindowTitle(tr("登陆"));
    resize(300,200);
}

void CLoginDlg::accept()
{
    if(usrLineEdit->text().trimmed()==tr("lcf")&&
            pwdLineEdit->text()==tr("lcf"))
    {
        QDialog::accept();
    }
    else
        QMessageBox::warning(this,tr("警告"),
                             tr("用户或密码错误!"),
                             QMessageBox::Yes);
    usrLineEdit->setFocus();
}
注:

1、通常编辑框QLineEdit窗口部件的显示方式有下列几种方式:

1.1 QLineEdit::Normal,默认的显示方式,显示用户实际输入的内容;

1.2 QLineEdit::Password,用星号“*”代替用户实际输入的内容;

1.3    QLineEdit::NoEcho,不显示用户输入的任何内容;

1.4    QLineEdit::PasswordEchoOnEdit,仅仅用户在行编译框里编辑文本时,才显示用户输入的字符,而在用户完成编辑后以"*"代替输入的内容;


2、函数QGridLayout::addWidget()将先前生成的标签和行编辑框添加到网格管理器gridLayout中。在上面的代码中,gridLayout->addWidget(usrLineEdit,0,1,1,3)函数共5个参数,实参usrLineEdit指出哪一个窗口部件将被放置在网格布局管理器中,第2,3个实参确定部件所在的行号和列号,后两个参数分别表示行的跨度和列的跨度。


3、函数QHBoxLayout::setSpacing()设置水平布局管理器btnLayout对象内部窗口部件之间的间隔为60。


4、函数QVBoxLayout::setMargin()设置布局管理器dlgLayout边框的宽度为40,即其内部子窗口部件距离布局管理器边界(布局管理器的边界是不可见的)的距离为40。


5、函数QVBoxLayout::addStretch()函数在垂直布局管理器dlgLayout对象中加入一个大小为40的strech,这将使得布局管理器gridLayout和btnLayout之间的默认距离设置为40,当同时上下拉伸对话框时,该strech可以*伸缩,从而保证gridLayout和btnLayout管理器内部各窗口部件的高度以及彼此间的垂直距离保持不变。


6、QMessageBox::warning()将会创建并显示一个模态的警告对话框,提示用户输入的用户名或密码错误。


7、QLineEdit::setFocus将鼠标的焦点定位到行编辑框对象usrLineEdit,以方便用户进行“用户名”和“密码”的修改。

8、QMessageBox类提供了显示操作信息的几种模态对话框:

8.1 QMessageBox::about,一个仅仅带又标题和简单文本的消息框;

8.2 QMessageBox::aboutQt,显示关于Qt的消息框;

8.3 QMessageBox::information,一个具有主题和提示文本的提示消息框; 

8.4 QMessageBox::question,一个具有标题和文本信息的询问消息框;

8.5 QMessageBox::warning,一个具有标题和文本信息的警告消息框;

8.6 QMessageBox::critical,一个具有标题和文本信息的致命错误消息框;


mydialog.cpp

#include<QtGui/QtGui>
#include"logindlg.h"
int main(int argc,char *argv[])
{
    QApplication app(argc,argv);
    QTextCodec::setCodecForTr(QTextCodec::codecForName("gb18030"));
    CLoginDlg dlg;
    return dlg.exec();

}

注:对话框分两种类型:

模态(modal)对话框和非模态(modeless)对话框;

模态对话框在没有消失之前用户不能与同一个应用程序的其他窗口进行交互,直到该对话框关闭;

非模态对话框被打开后,用户既可以选择与该对话框进行交互,也可以选择与应用程序的其他窗口进行交互。

非模态对话框若是栈对象,当代码退出对话框对象的作用域后,该对话框就自动销毁了,这将造成用户来不及和对话框进行交互,对话框就消失了。因此,必须通过new操作在堆中创建非模态对话框。

Qt中,QDialog::exec()以模态方式显示对话框,QDialog::show()默认以非模态方式显示对话框;