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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在 macOS 上,你可以使用系统自带的 终端(Terminal) 工具,通过 SSH 协议远程连接服务器

文章目录 1. 打开终端2. 使用 SSH 命令连接服务器3. 输入密码4. 连接成功5. 使用密钥登录&#xff08;可选&#xff09;6. 退出 SSH 连接7. 其他常用 SSH 选项8. 常见问题排查问题 1&#xff1a;连接超时问题 2&#xff1a;权限被拒绝&#xff08;Permission denied&#xff09…

关于大一上的总结

大一上总结 前言 源于学长们都喜欢写总结&#xff0c;今晚也正好听见一首有点触动心灵的歌&#xff0c;深有感慨&#xff0c;故来此写下这篇总结 正文 1.暑假前的准备 暑假之前姑且还是学习了基本的C语法&#xff0c;大概是到了结构体的地方&#xff0c;进度很慢&#xff0…

Spring Cloud Gateway-自定义异常处理

参考 https://blog.csdn.net/suyuaidan/article/details/132663141&#xff0c;写法不同于注入方式不一样 ErrorWebFluxAutoConfiguration Configuration(proxyBeanMethods false) ConditionalOnWebApplication(type ConditionalOnWebApplication.Type.REACTIVE) Condition…

121.【C语言】数据结构之快速排序(未优化的Hoare排序存在的问题)以及时间复杂度的分析

目录 1.未优化的Hoare排序存在的问题 测试代码 "量身定制"的测试代码1 运行结果 "量身定制"的测试代码2 运行结果 "量身定制"的测试代码3 运行结果 分析代码1、2和3栈溢出的原因 排有序数组的分析 分析测试代码1:给一个升序数组,要求排…

如何使用 `uiautomator2` 控制 Android 设备并模拟应用操作_VIVO手机

在 Android 自动化测试中,uiautomator2 是一个非常强大的工具,能够帮助我们通过 Python 控制 Android 设备执行各种操作。今天,我将通过一个简单的示例,介绍如何使用 uiautomator2 控制 Android 设备,执行特定的应用启动、广告跳过以及其他 UI 操作。此示例的目标是自动化…

Swift Combine 学习(七):实践应用场景举例

Swift Combine 学习&#xff08;一&#xff09;&#xff1a;Combine 初印象Swift Combine 学习&#xff08;二&#xff09;&#xff1a;发布者 PublisherSwift Combine 学习&#xff08;三&#xff09;&#xff1a;Subscription和 SubscriberSwift Combine 学习&#xff08;四&…

使用 PyInstaller 和 hdiutil 打包 Tkinter 应用为 macOS 可安装的 DMG 文件

在这篇文章中&#xff0c;我们将逐步演示如何将基于 Python 的 Tkinter 应用程序打包成一个 macOS .app 文件&#xff0c;并将其封装为 .dmg 文件&#xff0c;供用户安装。 环境准备 在开始之前&#xff0c;请确保您的开发环境满足以下条件&#xff1a; macOS 系统。安装了 …

DC-2 靶场渗透

目录 环境搭建 开始渗透 扫存活 扫端口 扫服务 看一下80端口 看一下指纹信息 使用wpscan扫描用户名 再使用cewl生成字典 使用wpscan爆破密码 登陆 使用7744端口 查看shell rbash绕过 切换到jerry用户 添加环境变量 现在可以使用su命令了 提权 使用git提权 环…

如何在 Ubuntu 22.04 上优化 Apache 以应对高流量网站教程

简介 在本教程中&#xff0c;我们将学习如何优化 Apache 以应对高流量网站。 当运行高流量网站时&#xff0c;确保你的 Apache Web 服务器得到优化对于有效处理负载至关重要。在本指南中&#xff0c;我们将介绍配置 Apache 以提高性能和可扩展性的基本技巧。 为高流量网站优…

安卓NDK视觉开发——手机拍照文档边缘检测实现方法与库封装

一、项目创建 创建NDK项目有两种方式&#xff0c;一种从新创建整个项目&#xff0c;一个在创建好的项目添加NDK接口。 1.创建NDK项目 创建 一个Native C项目&#xff1a; 选择包名、API版本与算法交互的语言&#xff1a; 选择C版本&#xff1a; 创建完之后&#xff0c;可…

02.01、移除重复节点

02.01、[简单] 移除重复节点 1、题目描述 编写代码&#xff0c;移除未排序链表中的重复节点。保留最开始出现的节点。 2、解题思路 为了实现这一目标&#xff0c;我们可以使用一个哈希表&#xff08;或集合&#xff09;来记录已经遇到的节点值&#xff0c;逐步遍历链表并删…

反向传播算法的偏置更新步骤

偏置的更新步骤 假设我们有一个三层神经网络&#xff08;输入层、隐藏层和输出层&#xff09;&#xff0c;并且每层的激活函数为 sigmoid 函数。我们需要更新隐藏层和输出层的偏置。以下是详细的步骤&#xff1a; 1. 计算误差项&#xff08;Error Term&#xff09; 输出层的…

【Ubuntu】不能连上网络

1. ping路由器的IP地址 ping 192.168.1.1 如果ping不通的话&#xff0c;可能是网络故障导致的。需要重启配置ip地址。配置文件 sudo vi /etc/network/interface 2. ping 8.8.8.8 如果ping不通的话&#xff0c;可能是路由器不能链接往外网&#xff1b; 或者路由器显示了当…

深入解析爬虫中的算法设计:提升效率与准确度

在网络爬虫&#xff08;Web Scraping&#xff09;中&#xff0c;设计高效、准确的算法是关键&#xff0c;尤其当面对大量数据或复杂的网站结构时&#xff0c;精心设计的爬虫算法能显著提高爬取速度并提升数据提取的准确性。本篇博客将详细讲解爬虫算法的设计与优化策略&#xf…

《C++设计模式》策略模式

文章目录 1、引言1.1 什么是策略模式1.2 策略模式的应用场景1.3 本文结构概览 2、策略模式的基本概念2.1 定义与结构2.2 核心角色解析2.2.1 策略接口&#xff08;Strategy&#xff09;2.2.2 具体策略实现&#xff08;ConcreteStrategy&#xff09;2.2.3 上下文&#xff08;Cont…

Spring源码分析之事件机制——观察者模式(一)

目录 事件基类定义 事件监听器接口 事件发布者接口及实现 事件广播器实现 小小总结 Spring源码分析之事件机制——观察者模式&#xff08;一&#xff09;-CSDN博客 Spring源码分析之事件机制——观察者模式&#xff08;二&#xff09;-CSDN博客 Spring源码分析之事件机制…

Spring Security(maven项目) 3.0.2.4版本

前言&#xff1a; 通过实践而发现真理&#xff0c;又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识&#xff0c;又从理性认识而能动地指导革命实践&#xff0c;改造主观世界和客观世界。实践、认识、再实践、再认识&#xff0c;这种形式&#xff0c;循环往…

stm32 移植RTL8201F(正点原子例程为例)

最近在工作中需要使用RTL8201F&#xff0c;在网上找了很多帖子&#xff0c;没有找到合适的&#xff0c;自己翻资料移植了一个。 模板工程使用的是正点原子的f407探索版的例程&#xff0c;原子使用的是LAN8720,需要把他的驱动修改成为我们自己用的RTL8201F。 1.将PHY_TYPE改成我…

Unity学习笔记(四)如何实现角色攻击、组合攻击

前言 本文为Udemy课程The Ultimate Guide to Creating an RPG Game in Unity学习笔记 实现动画 首先实现角色移动的动画&#xff0c;动画的实现过程在第二篇&#xff0c;这里仅展示效果 attack1 触发攻击动画 实现脚本 接下来我们通过 Animator 编辑动画之间的过渡&#…

redis的集群模式与ELK基础

一、redis的集群模式 1.主从复制 &#xff08;1&#xff09;概述 主从模式&#xff1a;这是redis高可用的基础&#xff0c;哨兵和集群都是建立在此基础之上。 主从模式和数据库的主从模式是一样的&#xff0c;主负责写入&#xff0c;然后把写入的数据同步到从服务器&#xff…