Qt从入门到入土(七)-实现炫酷的登录注册界面(下)

前言

Qt从入门到入土(六)-实现炫酷的登录注册界面(上)主要讲了如何使用QSS样式表进行登录注册的界面设计,本篇文章将介绍如何对登录注册界面进行整体控件的布局,界面的切换以及实现登录、记住密码等功能。

创建登录页面

QWidget *Dialog::createLoginPage()
{
    QWidget* w=new QWidget(this);
    m_usernameEdit=new QLineEdit();
    m_passwordEdit=new QLineEdit();
    m_remPswChk=new QCheckBox("记住密码");
    m_goRgeBtn=new QPushButton("没有账号?去注册");
    m_loginBtn=new QPushButton("登 录");
    //水平布局
    QHBoxLayout* hlayout=new QHBoxLayout();
    hlayout->addWidget(m_remPswChk);
    hlayout->addWidget(m_goRgeBtn);
    //垂直布局
    QVBoxLayout* vlayout=new QVBoxLayout(w);
    vlayout->addWidget(m_usernameEdit);
    vlayout->addWidget(m_passwordEdit);
    vlayout->addLayout(hlayout);
    vlayout->addWidget(m_loginBtn);
    return w;
}

初始化登录页面

//创建登录页面
QWidget* loginPage=createLoginPage();
loginPage->setParent(this);

//移动登录页面到合适位置
loginPage->move(462,185);

创建注册页面

QWidget *Dialog::createRegPage()
{
    QWidget* w=new QWidget;
    m_reg_usernameEdit=new QLineEdit;
    m_reg_pwdEdit=new QLineEdit;
    m_reg_rePwdEdit=new QLineEdit;
    m_goLoginBtn=new QPushButton("去登陆");
    m_regBtn=new QPushButton("注 册");

    //水平布局
    QHBoxLayout* hlayout=new QHBoxLayout;
    hlayout->addWidget(m_goLoginBtn);
    hlayout->addWidget(m_regBtn);

    //垂直布局
    QVBoxLayout* vlayout=new QVBoxLayout(w);
    vlayout->addWidget(m_reg_usernameEdit);
    vlayout->addWidget(m_reg_pwdEdit);
    vlayout->addWidget(m_reg_rePwdEdit);
    vlayout->addLayout(hlayout);

    return w;
}

初始化注册页面

//创建注册页面
QWidget* regPage=createRegPage();
regPage->setParent(this);
regPage->move(462,185);

堆栈窗口

使用QStackedWidget来存放登录和注册页面从而方便实现交互

//创建堆栈窗口
QStackedWidget* stackWidget=new QStackedWidget(this);
stackWidget->addWidget(createLoginPage());  //默认是这个窗口
stackWidget->addWidget(createRegPage());
stackWidget->setGeometry(455,150,200,240);

登录和注册页面交互

//与登录页面建立联系
connect(m_goLoginBtn,&QPushButton::clicked,[this]()
        {
            this->m_stk->setCurrentIndex(0);  //设置当前堆栈窗口索引
        });

//与注册页面建立联系
connect(m_goRgeBtn,&QPushButton::clicked,[this]()
        {
    this->m_stk->setCurrentIndex(1);  //设置当前堆栈窗口索引
       });

当前效果

到这一步整个登录注册界面基本上就已经完成了,接下来就是进行界面的美化操作。

登录注册页面美化

在QSS中对控件进行美化

美化文本框

qss中设置无边框文本框

QLineEdit
{
border:none;
border-bottom-width:1px;
border-bottom-color:rgb(223,223,223);
border-bottom-style:solid;
font-size:14px;
height:40px;
}

QLineEdit:hover
{
border-bottom-color:rgb(127,127,127);
}

设置文本提示

//设置文本提示
m_usernameEdit->setPlaceholderText("用户名");
m_passwordEdit->setPlaceholderText("密码");

//设置文本提示
m_reg_usernameEdit->setPlaceholderText("用户名");
m_reg_pwdEdit->setPlaceholderText("密码");
m_reg_rePwdEdit->setPlaceholderText("确认密码");

效果

设置对象名

设置对象名,便于在qss中对指定控件特殊化处理

//设置对象名
m_goLoginBtn->setObjectName("goLoginBtn");
m_regBtn->setObjectName("regBtn");

m_goRgeBtn->setObjectName("goRgeBtn");
m_remPswChk->setObjectName("remPswChk");
m_loginBtn->setObjectName("loginBtn");

美化复选框

QCheckBox
{
color:rgb(127,127,127);
}

QCheckBox:hover
{
color:rgb(120,45,255);
}

QCheckBox::indicator
{
border-image:url(":/Resources/images/uncheck.png");
}

QCheckBox::indicator:checked
{
border-image:url(":/Resources/images/check.png");
}

美化按钮

美化登录界面按钮

美化去注册按钮

QPushButton#goRgeBtn
{
border:none;
color:rgb(127,127,127);
}

QPushButton#goRgeBtn:hover
{
border:none;
color:rgb(120,45,255);
}

美化登录按钮

QPushButton#loginBtn
{
border:none;
border-radius:5px;
/*线性渐变*/
background:qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgb(11,194,255), stop:1 rgb(0,182,250));
font-size:14px;
color:white;
height:30px;
}

QPushButton#loginBtn:hover
{
 background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgb(34,203,255), stop:1 rgb(26,194,251));
}

美化注册界面按钮

设置水平布局两控件间隔为0

hlayout->setSpacing(0);

qss对去登陆和注册按钮控件的美化

QPushButton#goLoginBtn,#regBtn
{
border:none;
color:white;
font-size:12px;
height:30px;
}
QPushButton#goLoginBtn
{
border-top-left-radius:5px;
background:rgb(255,58,5);
width:120px;
}

QPushButton#goLoginBtn:hover
{
background:rgb(227,0,0);
}

QPushButton#regBtn
{
border-bottom-right-radius:5px;
background:rgb(6,255,238);
}

QPushButton#regBtn:hover
{
background:rgb(5,227,212);
}

响应登录和注册

使用QLabel来设置登录注册提示(登录注册失败、登录注册成功、账号密码输入错误等等)

初始化提示标签

//初始化提示标签
m_tipLab=new QLabel(this);
//设置位置
m_tipLab->setGeometry(454,375,200,30);
//设置居中显示
m_tipLab->setAlignment(Qt::AlignCenter)
//设置颜色
m_tipLab->setStyleSheet("color:red;");

初始化定时器

主要为了实现提示信息过段时间消失

//初始化定时器
m_timer=new QTimer(this);
//设置定时器结束
m_timer->callOnTimeout([this](){
    m_tipLab->clear();
    m_timer->stop();
});

提示信息函数

void Dialog::setTipMsg(const QString &msg, int msec)
{
    m_tipLab->setText(msg);
    //判断是否连续点击
    if(m_timer->isActive())
        m_timer->stop();
    m_timer->start(msec);
}

设置密码掩膜

//设置密码掩膜
m_reg_pwdEdit->setEchoMode(QLineEdit::Password);
m_reg_rePwdEdit->setEchoMode(QLineEdit::Password);

m_passwordEdit->setEchoMode(QLineEdit::Password);

登录与注册响应函数

void Dialog::onLogin()
{
    //账号密码检查
    auto username=m_usernameEdit->text();
    auto password=m_passwordEdit->text();

    if(username.isEmpty()||password.isEmpty())
    {
        setTipMsg("账号或密码不能为空!");
        return;
    }
    if(username.size()<5)
    {
        setTipMsg("账号长度有误!");
        return;
    }
    if(password.size()<8)
    {
        setTipMsg("密码长度有误!");
        return;
    }
}

void Dialog::onRegister()
{
    //账号密码检查
    auto username=m_reg_usernameEdit->text();
    auto password=m_reg_pwdEdit->text();
    auto rePsw=m_reg_rePwdEdit->text();

    if(username.isEmpty()||password.isEmpty())
    {
        setTipMsg("账号或密码不能为空!");
        return;
    }
    if(username.size()<5)
    {
        setTipMsg("账号长度有误!");
        return;
    }
    if(password.size()<8)
    {
        setTipMsg("密码长度有误!");
        return;
    }
    if(password!=rePsw)
    {
        setTipMsg("两次密码输入不一致!");
        return;
    }

}

把登录按钮设为焦点

本程序默认关闭按钮是焦点,也就是说按下回车登录界面就会关闭,所以应该要把登录按钮设置为焦点。

//取消焦点
closeBtn->setFocusPolicy(Qt::NoFocus);

//取消焦点
m_goRgeBtn->setFocusPolicy(Qt::NoFocus);
//设置焦点
m_loginBtn->setDefault(true);

登录成功后进入主界面

//账号密码与设定一致时
if(username=="admin"&&password=="admin")
    this->accept();

//登录

{
    Dialog w;
    auto ret=w.exec();
    if(ret!=QDialog::Accepted)
        return 0;
}
//登录成功进入主窗口
QWidget homeW;
homeW.show();

保存登录成功的账号密码到应用程序

qApp->setProperty("username",username);
qApp->setProperty("password",password);

qInfo()<<qApp->property("username")<<qApp->property("password");

实现记住密码以及保存账号和密码到指定文件

设置应用程序名

qApp->setApplicationName("LogRegAPP");

使用QSettings来存储和访问应用程序的设置和配置

QSettings settings(filepath,QSettings::Format::IniFormat);
//setValue方法用于将键值对存储到配置文件中
settings.setValue("remPswChk",m_remPswChk->isChecked());
settings.setValue("username",username);
settings.setValue("password",password);

使用QStandardPaths来获取应用程序本地数据位置路径

auto path=QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);

生成配置文件路径

QString configPath()
{
    //如果成功则返回到本地应用程序位置路径,否则返回当前文件夹
    auto path=QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
    QDir dir;
    if(dir.mkpath(path))
    {
        if(dir.cd(path))
        {
            return dir.path()+"/"+"LogRegAPP.ini";
        }
    }
    return "LogRegAPP.ini";
}

读取配置文件中的信息

//获取配置文件中的信息
QSettings settings(configPath(),QSettings::Format::IniFormat);
//如果settings.value()返回的值不是空,它将被转换为true,否则为false。
m_remPswChk->setChecked(settings.value("remPswChk",false).toBool());
//如果找不到该设置,它将默认为一个空字符串""。
m_usernameEdit->setText(settings.value("username","").toString());
if (m_remPswChk->isChecked()) {
    m_passwordEdit->setText(settings.value("password", "").toString());
}

整体效果

点击记住密码,当每次登录完成后,下次登陆就会自动从配置文件中读取信息填写账号密码,到这里,这个项目就大体完成了,但还是有需要完善的地方,如账号密码安全性、支持多个账号等等,后续有时间会继续完善的。

总结

本次登录注册项目,涉及到了qss界面设计和美化、图形界面绘制、控件布局设计以及一些实际功能的逻辑算法,对于初学者来说是非常友好的,是一个适合入门的项目。但还不够完美,有待进一步的完善。文笔不好请见谅,要是有问题欢迎在评论区留言或者私信我,也欢迎指出我的不足,感谢观看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/946297.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智能化人才招聘系统是怎样的?

随着企业规模的扩大和业务范围的拓展&#xff0c;人才招聘成为了企业发展的关键环节。然而&#xff0c;市面上的人才招聘系统琳琅满目&#xff0c;质量参差不齐&#xff0c;许多企业发现&#xff0c;并非所有系统都能满足他们的需求&#xff0c;特别是智能化的需求。今天&#…

论文分享 | PromptFuzz:用于模糊测试驱动程序生成的提示模糊测试

大语言模型拥有的强大能力可以用来辅助多种工作&#xff0c;但如何有效的辅助仍然需要人的精巧设计。分享一篇发表于2024年CCS会议的论文PromptFuzz&#xff0c;它利用模型提示生成模糊测试驱动代码&#xff0c;并将代码片段嵌入到LLVM框架中执行模糊测试。 论文摘要 制作高质…

[最佳方法] 如何将视频从 Android 发送到 iPhone

概括 将大视频从 Android 发送到 iPhone 或将批量视频从 iPhone 传输到 Android 并不是一件容易的事情。也许您已经尝试了很多关于如何将视频从 Android 发送到 iPhone 15/14 的方法&#xff0c;但都没有效果。但现在&#xff0c;通过本文中的这 6 种强大方法&#xff0c;您可…

cesium小知识: 处理动画的5种方式

在 Cesium 中处理动画可以通过多种方式实现,具体取决于你想要创建的动画类型。Cesium 提供了丰富的API来支持不同种类的动画,包括但不限于物体的移动、旋转、缩放、属性变化等。以下是几种常见的动画处理方法: 1. 使用 Entity 和 SampledProperty 对于动态数据或随时间变化…

003:如何理解 CNN 中的 RGB 图像和通道?

本文为合集收录&#xff0c;欢迎查看合集/专栏链接进行全部合集的系统学习。 合集完整版请参考这里。 在灰度图一节的最后&#xff0c;给出了一个由彩色图片转成灰度图的示例&#xff0c;并且通过 color_image.mode获取了图片的格式&#xff1a;彩色图片获取到的格式为 RGBA&a…

小程序基础 —— 07 创建小程序项目

创建小程序项目 打开微信开发者工具&#xff0c;左侧选择小程序&#xff0c;点击 号即可新建项目&#xff1a; 在弹出的新页面&#xff0c;填写项目信息&#xff08;后端服务选择不使用云服务&#xff0c;开发模式为小程序&#xff0c;模板选择为不使用模板&#xff09;&…

TP 钱包插件版本的使用

目前 TokenPocket 的几个平台中&#xff0c;以 ios 和 安卓版本最为常见&#xff0c;其实很少有人知道&#xff0c;浏览器上有一个插件版本的 Tp, 用电脑多的话&#xff0c;这也是一个挺好的选择。 最新版本现在支持Chrome、Brave 浏览器、Edge&#xff08;Firefox及Opera正在…

【AIGC】使用Java实现Azure语音服务批量转录功能:完整指南

文章目录 引言技术背景环境准备详细实现1. 基础架构设计2. 实现文件上传功能3. 提交转录任务crul4. 获取转录结果 使用示例结果示例最佳实践与注意事项总结 引言 在当今数字化时代&#xff0c;将音频内容转换为文本的需求越来越普遍。无论是会议记录、视频字幕生成&#xff0c…

【UVM】搭建一个验证平台

UVM环境组件 组件功能 sequence_item&#xff1a;包装数据 UVM中&#xff0c;所有的transaction都要从uvm_sequence_item派生sequence item是每一次driver与DUT互动的最小粒度内容sequence&#xff1a;产生数据 uvm_sequence是一个参数化的类&#xff0c;其参数是transactio…

用Python操作字节流中的Excel文档

Python能够轻松地从字节流中加载文件&#xff0c;在不依赖于外部存储的情况下直接对其进行读取、修改等复杂操作&#xff0c;并最终将更改后的文档保存回字节串中。这种能力不仅极大地提高了数据处理的灵活性&#xff0c;还确保了数据的安全性和完整性&#xff0c;尤其是在网络…

.Net加密与Java互通

.Net加密与Java互通 文章目录 .Net加密与Java互通前言RSA生成私钥和公钥.net加密出数据传给Java端采用java方给出的公钥进行加密采用java方给出的私钥进行解密 .net 解密来自Java端的数据 AES带有向量的AES加密带有向量的AES解密无向量AES加密无向量AES解密 SM2(国密)SM2加密Sm…

elasticsearch-java客户端jar包中各模块的应用梳理

最近使用elasticsearch-java客户端实现对elasticsearch服务的Api请求&#xff0c;现对elasticsearch-java客户端jar包中各模块的应用做个梳理。主要是对co.elastic.clients.elasticsearch路径下的各子包的简单说明。使用的版本为&#xff1a;co.elastic.clients:elasticsearch-…

119.【C语言】数据结构之快速排序(调用库函数)

目录 1.C语言快速排序的库函数 1.使用qsort函数前先包含头文件 2.qsort的四个参数 3.qsort函数使用 对int类型的数据排序 运行结果 对char类型的数据排序 运行结果 对浮点型数据排序 运行结果 2.题外话:函数名的本质 1.C语言快速排序的库函数 cplusplus网的介绍 ht…

JVM实战—G1垃圾回收器的原理和调优

1.G1垃圾回收器的工作原理 (1)ParNew CMS的组合有哪些痛点 Stop the World是最大的问题。无论是新生代GC还是老年代GC&#xff0c;都会或多或少产生STW现象&#xff0c;这对系统的运行是有一定影响的。 所以JVM对垃圾回收器的优化&#xff0c;都是朝减少STW的目标去做的。在这…

HuatuoGPT-o1:基于40K可验证医学问题的两阶段复杂推理增强框架,通过验证器引导和强化学习提升医学模型的推理能力

HuatuoGPT-o1&#xff1a;基于40K可验证医学问题的两阶段复杂推理增强框架&#xff0c;通过验证器引导和强化学习提升医学模型的推理能力 论文大纲理解1. 确认目标2. 分析过程3. 实现步骤4. 效果展示 解法拆解全流程提问俩阶段详细分析 论文&#xff1a;HuatuoGPT-o1, Towards …

HTML——45.单元格合并

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>表格</title></head><body><!--合并单元格&#xff1a;1.在代码中找到要合并的单元格2.在要合并的所有单元格中&#xff0c;保留要合并的第一个单元格…

electron在arm64架构交叉编译遇到libnotify/notify.h文件找不到错误记录

问题描述 在按照官方文档进行arm64下electron编译时出现下面的错误&#xff0c;编译环境为ubuntun22.04.5。 问题分析 由于当前目标架构是arm64&#xff0c;所以从上图可知sysroot为build/linux/debian_bullseye_arm64-sysroot&#xff0c;进入到该目录下查看libnotify的头文…

我的创作纪念日与2024年年报

我的创作纪念日 机缘 原来是你&#xff01; 收获 在创作的过程中都有哪些收获 获得了14668粉丝的关注。获得了正向或者反向的反馈&#xff1a;1万多赞、426评论、140多万阅读量等。认识和哪些志同道合的领域同行&#xff1a;有且再寻觅。 日常 &#x1f3e0;个人主页&…

点击锁定按钮,锁定按钮要变成解锁按钮,然后状态要从待绑定变成 已锁定(升级版)

文章目录 1、updateInviteCodeStatus2、handleLock3、InviteCodeController4、InviteCodeService5、CrudRepository 点击锁定按钮&#xff0c;锁定按钮要变成解锁按钮&#xff0c;然后状态要从待绑定变成 已锁定&#xff1a;https://blog.csdn.net/m0_65152767/article/details…

使用npm包的工程如何引入mapboxgl-enhance/maplibre-gl-enhance扩展包

作者&#xff1a;刘大 前言 在使用iClient for MapboxGL/MapLibreGL项目开发中&#xff0c;往往会对接非EPSG:3857坐标系的地图&#xff0c;由于默认不支持&#xff0c;因此需引入mapboxgl-enhance/maplibre-gl-enhance扩展包。 在使用Vue等其他框架&#xff0c;通过npm包下载…