输入框小设计
目的:实现鼠标点击输入框时的聚焦效果。
首先在LoginForm构造函数中为账号和密码输入框添加事件过滤器。关于事件过滤器的具体介绍可以参考这篇博文:Qt消息机制和事件
ui->nameEdit->installEventFilter(this);
ui->pwdEdit->installEventFilter(this);
在eventFilter()中实现:
- 当鼠标点击输入框时,即
event->type() == QEvent::FocusIn
时,将输入框的字体颜色变深 - 当不输入时,若输入框中无内容,则将输入框字体颜色变浅
bool LoginForm::eventFilter(QObject* watched, QEvent* event)
{
if(ui->passwdEdit == watched)
{
if(event->type() == QEvent::FocusIn)
{
ui->passwdEdit->setStyleSheet("color: rgb(1,1,1);background-color: transparent;");
}
else if(event->type() == QEvent::FocusOut)
{
if(ui->passwdEdit->text().size() == 0)
{
ui->passwdEdit->setStyleSheet("color: rgb(158,158,158);background-color: transparent;");
}
}
}
else if(ui->nameEdit == watched)
{
if(event->type() == QEvent::FocusIn)
{
ui->nameEdit->setStyleSheet("color: rgb(1,1,1);background-color: transparent;");
}
else if(event->type() == QEvent::FocusOut)
{
if(ui->nameEdit->text().size() == 0)
{
ui->nameEdit->setStyleSheet("color: rgb(158,158,158);background-color: transparent;");
}
}
}
return QWidget::eventFilter(watched, event);
}
最终记得返回原有的事件过滤函数 ,以便在处理完自定义过滤器逻辑后,将其余事件传递给父类处理。
实现效果:
- 未点击输入框时,字体颜色较浅。
- 点击输入框,字体颜色变深,实现聚焦效果。
- 输入内容时,默认占位文本消失,变成用户输入内容
(关于默认占位文本为何会消失这一点,是QWidget
类的成员函数setPlaceholderText()
本身实现的。在上篇博文中我们使用setPlaceholderText()
函数为输入框添加了默认占位文本,占位文本通常会在用户在输入框中未输入任何内容时显示,一旦用户开始输入内容,占位文本就会自动消失。)
添加忘记密码功能
首先添加一个文字内容为“忘记密码”的QLabel
,设置名称为forget
为forget
添加事件过滤器
ui->forget->installEventFilter(this);
在eventFilter()
函数中实现对forget
按下事件的处理
if((ui->forget == watched) && (event->type() == QEvent::MouseButtonPress))
{
QDesktopServices::openUrl(QUrl(QString(HOST) + "/forget"));
}
return QWidget::eventFilter(watched, event);
当点击forget之后,会跳转到对应的处理网页。
关于QDesktopServices的介绍
QDesktopServices
是Qt桌面服务类,它提供了一些方便的方法来访问桌面相关的功能。主要包括文件操作、URL打开、电子邮件发送等功能。
- 打开URL
QDesktopServices::openUrl(QUrl("http://www.example.com"));
这段代码可以用来在用户的系统默认浏览器中打开指定的URL。
- 打开文件
QDesktopServices::openUrl(QUrl::fromLocalFile("/path/to/your/file.txt"));
这段代码可以用来在系统中打开指定的文件。系统会使用默认的关联程序打开该文件。
- 发送邮件
QDesktopServices::openUrl(QUrl("mailto:recipient@example.com?subject=Hello&body=Hello%20there"));
这段代码可以用来打开默认的邮件客户端,并创建一个新的邮件写作窗口,填充收件人邮箱、主题和正文。
添加记住密码功能
添加一个文字为“记住密码”的CheckBox
,命名为remberPwd
。
在RecordFile的构造函数中,为m_config添加字段"remember",初始值为false。
m_config.insert("remember", false);//记住密码
在UI中右键checkBox,选择转到槽,选择重写状态改变stateChanged()
函数:
当checkBox的状态变化时,如果 “记住密码” 复选框被勾选,将用户名和密码保存到持久化存储中。(在后续博文实现)
如果取消勾选,则会删除保存的用户名和密码,同时取消自动登录。
取消自动登录功能将在下文介绍。
void LoginForm::on_remberPwd_stateChanged(int state)
{
//记住密码复选框状态改变
record->config()["remember"] = state == Qt::Checked;
if(state == Qt::Checked&&)
{
QString user = ui->nameEdit->text(); // 获取用户名输入框中的文本
QString pwd = ui->pwdEdit->text(); // 获取密码输入框中的文本
saveCredentials(user, pwd); // 将用户名和密码保存到持久化存储中
is_remembered=true;
}
else
{
is_remembered=false;
clearSavedCredentials(); // 清除保存的用户名和密码
ui->autoLoginCheck->setChecked(false);//关闭记住密码,则取消自动登录
}
}
从持久化存储中加载已保存的用户名和密码,并将其加载到输入框中。
void LoginForm::loadSavedCredentials()
{
QString user, pwd;
if(hasSavedCredentials(user, pwd)) // 检查是否存在已保存的用户名和密码
{
ui->nameEdit->setText(user); // 将已保存的用户名填充到用户名输入框中
ui->pwdEdit->setText(pwd); // 将已保存的密码填充到密码输入框中
}
}
对on_logoButton_released()
做如下修改。
若上一次登录已经记住密码,则加载记录中的账户密码。
获取输入框中的内容,若记住密码复选框被勾选,并且上一次没有记录密码(! is_remembered),则保存用户名和密码。
void LoginForm::on_logoButton_released()
{
if(is_remembered) loadSavedCredentials();
QString user = ui->nameEdit->text(); // 获取用户名输入框中的文本
QString pwd = ui->pwdEdit->text(); // 获取密码输入框中的文本
bool rememberPwd = ui->remberPwd->isChecked(); // 获取 "记住密码" 复选框的状态
if(rememberPwd&&!is_remembered)
{
saveCredentials(user, pwd); // 如果 "记住密码" 被勾选,保存用户名和密码
}
// 其他登录操作...
}
添加自动登录功能
添加“自动登录”CheckBox,命名autoLoginCheck。
在RecordFile的构造函数中,为m_config添加字段"auto",初始值为false。
m_config.insert("auto", false);//自动登录
当“自动登录”复选框状态变化时:
- 根据 “自动登录” 复选框的状态更新配置信息中的 “auto” 字段,如果状态为
Qt::Checked
,则设置 “auto” 字段为 true;否则设置为 false。 - 当 “自动登录” 被勾选时,将执行以下操作:
- 设置 “remember” 字段为 true,表示开启自动登录时会同时开启记住密码。
- 将 “记住密码” 复选框设置为勾选状态,保证自动登录时也会记住密码。
- 禁止用户修改 “记住密码” 复选框的状态。
- 当 “自动登录” 被取消勾选时,将执行以下操作:
- 允许用户修改 “记住密码” 复选框的状态。
void LoginForm::slots_autoLoginCheck_stateChange(int state)
{
record->config()["auto"] = state == Qt::Checked;
if(state == Qt::Checked)
{
record->config()["remember"] = true;
ui->remberPwd->setChecked(true);//自动登录会开启记住密码
}
else
{
ui->remberPwd->setCheckable(true);//启动修改状态
}
}
load_config()函数
用于加载用户配置信息并初始化界面状态的,并且根据配置信息来自动设置 “记住密码” 和 “自动登录” 复选框的状态,以及相应的用户名和密码输入框的文本内容。
在LoginForm构造函数的最后调用。
connect(ui->autoLoginCheck, SIGNAL(stateChanged(int)),
this, SLOT(slots_autoLoginCheck_stateChange(int)));
当 “自动登录” 复选框的状态改变时,会调用名为slots_autoLoginCheck_stateChange
的槽函数来处理状态改变。这样做是为了确保复选框状态的改变能够触发相应的处理逻辑。
QJsonObject& root = record->config();
从记录中获取用户的配置信息,并存储在 root 中。
ui->remberPwd->setChecked(root["remember"].toBool());
ui->autoLoginCheck->setChecked(root["auto"].toBool());
根据配置信息中的 “remember"和"auto” 字段的值来设置 “记住密码” 复选框的状态。
if(root["auto"].toBool()) //如果开启了自动登录,则检查用户名和密码是否ok
{
if(user.size() > 0 && pwd.size() > 0)
{
ui->nameEdit->setText(user);
ui->pwdEdit->setText(pwd);
ui->logoButton->setText(u8"取消自动登录");
auto_login_id = startTimer(3000);//给3秒的时间,方便用户终止登录过程
}
}
如果用户和密码都存在,会设置登录按钮的文本为 “取消自动登录”,表示可以取消自动登录。
启动一个 3 秒的定时器 (auto_login_id = startTimer(3000)),以便用户在登录过程中能够在 3 秒内取消自动登录的操作。
定时器
当定时器结束时,会触发timerEvent()
函数来处理定时器事件。
重写timeEvent()
函数,处理自动登录定时器事件的逻辑。一旦定时器触发,会从记录中获取用户的配置信息,然后使用配置的用户名和密码进行登录检查。
void LoginForm::timerEvent(QTimerEvent* event)
{
if(event->timerId() == auto_login_id)
{
killTimer(auto_login_id);
QJsonObject& root = record->config();
QString user = root["user"].toString();
QString pwd = root["password"].toString();
check_login(user, pwd);
}
}
实现了当3秒定时器结束时,会触发自动登录的操作。这样的设计可以让用户在一定时间内有机会取消自动登录,增加了用户对自动登录过程的控制。