【QT速成】零基础快速入门QT6简明教程之登陆对话框的实现(三)

简介: QT教程3

登录对话框的实现

设计师实现

创建好工程和设计师类后编写基本的主函数框架

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的设计师类中

image.png

单击元素可在其属性框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);


相关文章
|
2天前
|
编解码 Java 程序员
写代码还有专业的编程显示器?
写代码已经十个年头了, 一直都是习惯直接用一台Mac电脑写代码 偶尔接一个显示器, 但是可能因为公司配的显示器不怎么样, 还要接转接头 搞得桌面杂乱无章,分辨率也低,感觉屏幕还是Mac自带的看着舒服
|
4天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1541 5
|
1月前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
7天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
586 22
|
4天前
|
存储 SQL 关系型数据库
彻底搞懂InnoDB的MVCC多版本并发控制
本文详细介绍了InnoDB存储引擎中的两种并发控制方法:MVCC(多版本并发控制)和LBCC(基于锁的并发控制)。MVCC通过记录版本信息和使用快照读取机制,实现了高并发下的读写操作,而LBCC则通过加锁机制控制并发访问。文章深入探讨了MVCC的工作原理,包括插入、删除、修改流程及查询过程中的快照读取机制。通过多个案例演示了不同隔离级别下MVCC的具体表现,并解释了事务ID的分配和管理方式。最后,对比了四种隔离级别的性能特点,帮助读者理解如何根据具体需求选择合适的隔离级别以优化数据库性能。
201 3
|
10天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
11天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
581 5
|
23天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
7天前
|
XML 安全 Java
【Maven】依赖管理,Maven仓库,Maven核心功能
【Maven】依赖管理,Maven仓库,Maven核心功能
235 3
|
9天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
328 2