1、新建项目login1,不选择创建界面选项
这里我们依然创建了Qt Widgets应用,但是没有使用界面文件,这样就需要使用代码来实现界面。
2、创建登录对话框类。往项目中添加新文件,模板选择C++分类中的C++ Class,如下图所示。
类名:LoginDialog
基类:QDialog
设置完成后,先打开logindialog.h文件,将其内容修改如下图所示。
#ifndef LOGINDIALOG_H #define LOGINDIALOG_H #include<QDialog> class QLabel; class QLineEdit; class QPushButton; class LoginDialog : public QDialog { Q_OBJECT //使用信号和槽等特性必须添加该宏 public: explicit LoginDialog(QWidget *parent=0); ~LoginDialog(); private: QLabel *userLabel; QLabel *pwdLabel; QLineEdit *usrLineEdit; QLineEdit *pwdLineEdit; QPushButton *loginBtn; QPushButton *exitBtn; }; #endif // LOGINDIALOG_H
这里先添加了QDialog类的头文件,然后前置声明了QLabel、QLineEdit和QPushButton类,这是因为在下面只是定义了这些类对象的指针,并不需要该类完整的定义,所以可以将它们的包含语句放到源文件中进行。在LoginDialog类声明的开始需要添加Q_OBJECT宏才能使用信号和槽等元对象系统功能。在private部分定义了一些界面上需要的部件对象的指针。下面到logindialog.cpp文件中对这些部件对象进行初始化,其内容如下图所示。
#include "logindialog.h" #include<QLabel> #include<QLineEdit> #include<QPushButton> #include<QMessageBox> LoginDialog::LoginDialog(QWidget *parent):QDialog(parent) { userLabel=new QLabel(this); userLabel->move(70,80); userLabel->setText(tr("用户名")); usrLineEdit=new QLineEdit(this); usrLineEdit->move(140,80); usrLineEdit->setPlaceholderText(tr("请输入用户名")); pwdLabel=new QLabel(this); pwdLabel->move(70,130); pwdLabel->setText(tr("密码")); pwdLineEdit=new QLineEdit(this); pwdLineEdit->move(140,130); pwdLineEdit->setPlaceholderText(tr("请输入密码")); loginBtn=new QPushButton(this); loginBtn->move(50,200); loginBtn->setText(tr("登录")); exitBtn=new QPushButton(this); exitBtn->move(210,200); exitBtn->setText(tr("退出")); } LoginDialog::~LoginDialog() { }这里定义了构造函数和析构函数,在构造函数中对界面部件进行了初始化,设置了它们的位置及要显示的文本,这些代码实现的效果与前面在设计模式设置部件实现的效果是一样的。简单举例:move(70, 80)就是将部件左上角的坐标设置为(70, 80),这个坐标是父窗口部件的,这里就是登录对话框,对话框的左上角是(0, 0)点;setText()就是设置显示文本;setPlaceholderText()是设置占位符文本。
下面打开main.cpp文件,在其中使用登录对话框,更改代码如下图所示。
#include "mainwindow.h" #include <QApplication> #include"logindialog.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; LoginDialog dlg; if(dlg.exec()==QDialog::Accepted) { w.show(); return a.exec(); } }
编译程序:
3、实现功能
下面来实现两个按钮的功能,在Qt中,按钮按下功能是通过信号和槽来实现的,在前面的内容中我们已经看到三种方式来关联信号和槽了,下面来看下怎么使用代码自定义槽,然后手动进行关联。
首先在logindialog.h文件的类声明的最后添加如下代码:
#ifndef LOGINDIALOG_H #define LOGINDIALOG_H #include<QDialog> class QLabel; class QLineEdit; class QPushButton; class LoginDialog : public QDialog { Q_OBJECT //使用信号和槽等特性必须添加该宏 public: explicit LoginDialog(QWidget *parent=0); ~LoginDialog(); private: QLabel *userLabel; QLabel *pwdLabel; QLineEdit *usrLineEdit; QLineEdit *pwdLineEdit; QPushButton *loginBtn; QPushButton *exitBtn; //声明一个槽 private slots: void login(); }; #endif // LOGINDIALOG_H这样便声明了一个槽,其实槽就是一个函数,一般使用slots关键字,但在Qt 5新关联语法下也可以不使用该关键字,那么就可以像声明一般函数一样来声明槽,具体的内容我们将在后面章节中讲解,这里大家有个印象即可,一般建议使用slots关键字。
下面打开logindialog.cpp文件,在构造函数的最后添加如下图所示的两行代码。
#include "logindialog.h" #include<QLabel> #include<QLineEdit> #include<QPushButton> #include<QMessageBox> LoginDialog::LoginDialog(QWidget *parent):QDialog(parent) { userLabel=new QLabel(this); userLabel->move(70,80); userLabel->setText(tr("用户名")); usrLineEdit=new QLineEdit(this); usrLineEdit->move(140,80); usrLineEdit->setPlaceholderText(tr("请输入用户名")); pwdLabel=new QLabel(this); pwdLabel->move(70,130); pwdLabel->setText(tr("密码")); pwdLineEdit=new QLineEdit(this); pwdLineEdit->move(140,130); pwdLineEdit->setPlaceholderText(tr("请输入密码")); loginBtn=new QPushButton(this); loginBtn->move(50,200); loginBtn->setText(tr("登录")); exitBtn=new QPushButton(this); exitBtn->move(210,200); exitBtn->setText(tr("退出")); connect(loginBtn,&QPushButton::clicked,this,&LoginDialog::login); connect(exitBtn,&QPushButton::clicked,this,&LoginDialog::close); } LoginDialog::~LoginDialog() { }简单来说,第一个参数就是发射信号的部件,比如这里的loginBtn按钮;第二个参数是发射的信号,比如这里是QPushButton类的单击clicked()信号;第三个参数是接受信号的部件,比如这里是this即本部件也就是LoginDialog;第四个参数是要执行的槽,比如这里是LoginDialog类的login()。使用connect()函数就相当于以前在设计模式进行的关联设置。
下面在logindialog.cpp文件最后添加槽的定义,如下图所示。
#include "logindialog.h" #include<QLabel> #include<QLineEdit> #include<QPushButton> #include<QMessageBox> LoginDialog::LoginDialog(QWidget *parent):QDialog(parent) { userLabel=new QLabel(this); userLabel->move(70,80); userLabel->setText(tr("用户名")); usrLineEdit=new QLineEdit(this); usrLineEdit->move(140,80); usrLineEdit->setPlaceholderText(tr("请输入用户名")); pwdLabel=new QLabel(this); pwdLabel->move(70,130); pwdLabel->setText(tr("密码")); pwdLineEdit=new QLineEdit(this); pwdLineEdit->move(140,130); pwdLineEdit->setPlaceholderText(tr("请输入密码")); loginBtn=new QPushButton(this); loginBtn->move(50,200); loginBtn->setText(tr("登录")); exitBtn=new QPushButton(this); exitBtn->move(210,200); exitBtn->setText(tr("退出")); connect(loginBtn,&QPushButton::clicked,this,&LoginDialog::login); connect(exitBtn,&QPushButton::clicked,this,&LoginDialog::close); } LoginDialog::~LoginDialog() { } void LoginDialog::login(){ if(usrLineEdit->text().trimmed()==tr("root") &&pwdLineEdit->text().trimmed()==tr("123")){ accept(); } else{ QMessageBox::warning(this,tr("警告!"),tr("用户名或密码错误!"),QMessageBox::Yes); usrLineEdit->clear(); pwdLineEdit->clear(); usrLineEdit->setFocus(); } }
这里与前面示例中的代码是一样的,只不过usrLineEdit等部件调用不再需要使用ui对象。现在可以运行程序,已经实现了与使用设计模式相同的功能(密码显示样式可以在构造函数中使用pwdLineEdit->setEchoMode(QLineEdit::Password)来设置)。到这里,如果是初学者,可能会有很多很多疑问,这些疑问一时半会也讲不完,即便是这里都讲到,大家也理解不了,所以还是多动手敲代码,多练习,然后跟着教程往后学习,疑惑会越来越少的。
正确输入后: