登录对话框的实现
设计师实现
创建好工程和设计师类后编写基本的主函数框架
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
LoginDialog dlg;
//exec()是一个模态对话框的执行函数,它用于显示一个对话框并进入事件循环,等待对话框关闭后才返回。
//对于模态对话框来说,这意味着在对话框被关闭之前,用户不能与程序中的其他窗口交互
//这个方法会阻塞调用线程,并且只有在对话框关闭后才会返回一个值,这个值就是对话框的结果(接受或拒绝)。
if(dlg.exec() == QDialog :: Accepted)//如果对话框返回结果为QDialog::Accepted
{
w.show();
return a.exec();
}
else//如果结果不是 QDialog::Accepted
{
return 0;
}
}
并拖入组件在Logindialog.ui的设计师类中
单击元素可在其属性框objectName中键入元素变量名。这里将密码后面的行编辑器为pwdLineEdit,登录按钮为loginBtn,退出按钮为exitBtn。
在设计界面的下半部分选择Signals & Slots Editor窗口,点击“+”添加关联,依次修改发送者,信号,接收者,槽分别为exitBtn,clicked(),LoginDialog,close()。这一步就将exitBtn即退出按钮和LoginDialog窗口类关联在一起。当exitBtn被点击clicked()时就会发出信号到LoginDialog的槽中,同时会执行槽函数close()。
向登录的clicked()槽函数中写入:
void LoginDialog::on_loginBtn_clicked()
{
//accept();//对话框关闭并将结果设置为QDialog::Accepted
//这里trimmed()是QString类中的固有方法,使用其去除输入的前后的空白字符
if(ui->usrLineEdit->text().trimmed() == tr("meno")&&
ui->pwdLineEdit->text() == tr("xl20031027"))
{
accept();//返回结果QDialog::Accepted
}
else
{
QMessageBox :: warning(this,tr("警告"),tr("用户名和密码错误"),QMessageBox::Yes);
//输入错误后对行编辑器中的内容进行清除
ui->usrLineEdit->clear();//清除用户名编辑器
ui->pwdLineEdit->clear();//清除密码编辑器
ui->usrLineEdit->setFocus();//设置光标在用户名输入框
}
}
同时把密码行编辑器的属性中的echoMode属性选择为Password。即将输入的密码呈现为黑点不可见状态。再把密码行编辑器的placeholderText属性更改为“请输入密码”,将用户名行编辑器的更改为“请输入用户名”。
总结:以上几个工程里我们建立的设计师类Qt Widgets Designer Form Class, 选择不带任何按钮的Dialog without Buttons模板。这个类相当于子窗口,而主窗口则是我们建立工程时自带的mainwindow。我们这样进行创建工程方便对于工程的管理,便于实现不同的功能。
业内叫做MVC模式:
在Model-View-Controller(MVC)模式中,界面(View)通常与业务逻辑(Model)和用户交互(Controller)分开。创建独立的界面类有助于实现这种分离。
2.C++代码实现
实现思路如下(笔者亲自绘制):
创建工程后还是手动创建一个登录对话框的设计师类。
主函数:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
LoginDialog dlg;
if(dlg.exec() == QDialog :: Accepted)
{
w.show();
return a.exec();
}
else
{
return 0;
}
}
登录对话框.cpp代码:
#include "logindialog.h"
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QMessageBox>
LoginDialog::LoginDialog(QWidget *parent):QDialog(parent)
{
userLabel = new QLabel(this);//new动态创建一个QLabel对象分配给userLabel指针
userLabel ->move(70,80);//设置该对象在父窗口的位置
userLabel->setText(tr("用户名"));//设置该对象显示的文本
//注:tr()是Qt的翻译函数,用于支持国际化
userEditLine = new QLineEdit(this);
userEditLine -> move(140,80);
userEditLine -> setPlaceholderText(tr("请输入用户名"));
pwdLabel = new QLabel(this);
pwdLabel -> move(70,130);
pwdLabel -> setText(tr("密码"));
pwdEditLine = new QLineEdit(this);
pwdEditLine -> move(140,130);
pwdEditLine -> setPlaceholderText(tr("请输入密码"));
loginBtn = new QPushButton(this);
loginBtn -> move(50,200);
loginBtn -> setText(tr("登录"));
exitBtn = new QPushButton(this);
exitBtn -> move(210,200);
exitBtn -> setText(tr("退出"));
//信号与槽关联
//将loginBtn登录按钮的点击信号与设计师类的登录槽函数关联
connect(loginBtn,&QPushButton::clicked,this,&LoginDialog::login);
connect(exitBtn,&QPushButton::clicked,this,&LoginDialog::close);
}
//登录槽函数
void LoginDialog::login()
{
//判断用户名和密码是否正确
if(userEditLine->text().trimmed() == tr("meno")&&
pwdEditLine->text() == tr("xl20031027"))
{
accept();
}
else
{
QMessageBox::warning(this,tr("警告"),tr("用户名或者密码错误"),QMessageBox::Yes);
}
//清除内容,复位光标
userEditLine->clear();
pwdEditLine->clear();
userEditLine->setFocus();
}
LoginDialog::~LoginDialog()
{
}
登录对话框.h代码:
#ifndef LOGINDIALOG_H
#define LOGINDIALOG_H
#include <QDialog>
//前置声明要使用的类
class QLabel;
class QLineEdit;
class QPushButton;
class LoginDialog : public QDialog//LoginDialog继承了QDialog的公有属性
{
Q_OBJECT//QT的扩展宏,在类的私有或被保护部分出现,使得该类扩展了QT的元对象系统(包括信号和槽,元信息,内省,属性系统)
public://公有属性
//与类同名的为构造函数,用于对象创建时进行初始化
//explicit关键字表示其不能进行隐式类型转换
//该构造函数接收一个QWidget类型指针,指定了新建对话框的父窗口
//QWidget *parent = 0表示 parent 参数是可选的,如果调用者没有提供,则默认为 nullptr。
explicit LoginDialog(QWidget *parent = 0);
//在类同名函数前加上~为析构函数,用于在 LoginDialog 对象被销毁时释放其占用的资源。
~LoginDialog();
//槽函数
private slots:
void login();
private://私有属性
//用户名和密码标签
QLabel *userLabel;
QLabel *pwdLabel;
//用户名和密码编辑行
QLineEdit *userEditLine;
QLineEdit *pwdEditLine;
//退出和登录按钮
QPushButton *loginBtn;
QPushButton *exitBtn;
};
#endif // LOGINDIALOG_H
对"private slots"这句作解释:
槽(Slots):槽是普通的 C++ 成员函数,可以被信号调用。当你定义一个槽时,你实际上是在告诉 Qt,这个函数可以响应一个信号。槽可以有参数,也可以没有参数,并且可以像普通函数一样返回值。
对“userLabel = new QLabel(this);”这句作解释:
userLabel是.h文件中定义的"QLabel *userLabel;",new进行动态开辟内存空间的关键字修饰,使用组件QLabel的同名构造函数进行创建对象,并向其中传入this指针参数,意味着此句创建的对象的父对象为整个登录对话框对象LoginDialog。下面创建的对象也如此,它们的显示、位置和生命周期都由 LoginDialog 对象控制。当 LoginDialog 对象被销毁时,所有这些子组件也将被自动销毁。
对connect()函数作简单解释:
主要用于信号和槽的连接
定义为connect(lineEdit, &QLineEdit::textChanged, this, &Widget::do_textChanged);