QT登录界面系统
1、前言
|----------------------------------------------------------------------------------------------|
| 前言:设计一个登录界面,输入密码时过了1秒会变成*或者输入下一个密码,上一个直 接变成*,不用ui设计师,纯靠代码设计,在这里做个总结,可以分享给别人参考,也可 以巩固自己的学习。 |
1.1创建账号,密码标签
|---------|
| 在头文件中声明 |
cpp
QLabel* createLabel(const QString &text, int offsetX, int offsetY); //创建标签
|-----------|
| .cpp文件中实现 |
cpp
//创建标签
QLabel* MainWindow::createLabel(const QString &text, int offsetX, int offsetY)
{
QLabel *label = new QLabel(text, this);
setWindowGeometry(label, offsetX, offsetY);
return label;
}
|--------|
| 调用函数实现 |
cpp
//创建标签
accountNumberLabel = createLabel("账号", 50, 125);
passWorldLabel = createLabel("密码", 50, 80);
1.2创建账号,密码输入框
|---------|
| 在头文件中声明 |
cpp
QLineEdit* createLineEdit(int width, int offsetX, int offsetY); //创建输入框
|-----------|
| .cpp文件中实现 |
cpp
//创建输入框
QLineEdit* MainWindow::createLineEdit(int width, int offsetX, int offsetY)
{
QLineEdit *lineEdit = new QLineEdit(this);
setWindowGeometry(lineEdit, offsetX, offsetY, width - lineEdit->width());
return lineEdit;
}
|--------|
| 调用函数实现 |
cpp
//创建输入框
accountNumberLineEdit = createLineEdit(200, 10, 125);
// 密码输入框特殊设置
passWorldLineEdit = createLineEdit(200, 10, 80);
passWorldLineEdit->setEchoMode(QLineEdit::Normal);
passWorldLineEdit->installEventFilter(this);
1.3创建登录按钮
|---------|
| 在头文件中声明 |
cpp
void createLoginButton(int offsetX, int offsetY); //创建登录按钮
|-----------|
| .cpp文件中实现 |
cpp
//创建登录按钮
void MainWindow::createLoginButton(int offsetX, int offsetY)
{
login_button = new QPushButton("登录", this);
setWindowGeometry(login_button, offsetX, offsetY, -10, 10);
}
|--------|
| 调用函数实现 |
cpp
//创建登录按钮
createLoginButton(-210, 105);
1.4创建一个函数设置控件位置和大小
|---------|
| 在头文件中声明 |
cpp
void setWindowGeometry(QWidget *window, int offsetX, int offsetY, int widthW=0, int widthH=0); //设置控件位置和大小
|-----------|
| .cpp文件中实现 |
cpp
//设置控件位置和大小
void MainWindow::setWindowGeometry(QWidget *window, int offsetX, int offsetY, int widthW, int widthH)
{
int x = (this->width() - window->width()) / 2 - offsetX;
int y = (this->height() - window->height()) / 2 - offsetY;
window->setGeometry(x, y, window->width() + widthW,window->height() + widthH);
}
1.5登录验证
|----------------|
| 在头文件中声明登录按钮槽函数 |
cpp
void loginButton(); //登录按钮处理的槽函数
|-------------|
| 连接登录按钮的信号与槽 |
cpp
// 按钮点击事件
connect(login_button, &QPushButton::clicked, this, &MainWindow::loginButton);
|-----------|
| .cpp文件中实现 |
cpp
//设置控件位置和大小
// 登录验证
void MainWindow::loginButton()
{
QString account = accountNumberLineEdit->text();
QString password = visiblePassworld; // 使用存储的真实密码
if (account == "admin" && password == "123456") {
QMessageBox::information(this, "登录成功", "欢迎回来!");
} else {
QMessageBox::warning(this, "登录失败", "账号或密码错误");
}
}
1.6事件过滤器
|---------|
| 在头文件中声明 |
cpp
protected:
bool eventFilter(QObject *watched, QEvent *event) override; //事件过滤器
|-----------|
| .cpp文件中实现 |
cpp
// 事件过滤器实现
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
//检查密码输入框事件是否发生且事件是否为按键按下
if (watched == passWorldLineEdit && event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); //将通用事件对象转换为键盘事件对象
// 处理退格键
if (keyEvent->key() == Qt::Key_Backspace) {
if (!visiblePassworld.isEmpty()) {
visiblePassworld.chop(1); //删除一个字符
// 若密码为空则显示空字符串,否则显示n-1个星号 + 最后一个真实字符
QString displayText = visiblePassworld.isEmpty() ?
"" :
QString(visiblePassworld.length() - 1, '*') + visiblePassworld.right(1);
passWorldLineEdit->blockSignals(true);
passWorldLineEdit->setText(displayText);
passWorldLineEdit->blockSignals(false);
passWorldTimer->start(1000);
}
return true;
}
// 处理普通输入
else if (!keyEvent->text().isEmpty()) {
// 追加新字符到真实密码存储
visiblePassworld += keyEvent->text();
//根据 visiblePassworld 的长度来决定 displayText 的内容
QString displayText = (visiblePassworld.length() > 1) ?
QString(visiblePassworld.length() - 1, '*') + visiblePassworld.right(1) :
visiblePassworld;
passWorldLineEdit->blockSignals(true);
passWorldLineEdit->setText(displayText);
passWorldLineEdit->blockSignals(false);
passWorldTimer->start(1000); //启动定时器
return true;
}
}
// 其他事件交给父类处理
return QMainWindow::eventFilter(watched, event);
}
1.7密码定时器
|-------------------|
| 在头文件中声明密码定时器处理槽函数 |
cpp
void passWorld_startTimer(); //密码定时器处理槽函数
|---------------|
| 连接密码定时器处理信号与槽 |
cpp
// 按钮点击事件
connect(login_button, &QPushButton::clicked, this, &MainWindow::loginButton);
|-----------|
| .cpp文件中实现 |
cpp
// 定时器处理函数
void MainWindow::passWorld_startTimer()
{
if (!visiblePassworld.isEmpty()) {
QString displayText = QString(visiblePassworld.length(), '*'); //把密码变为*
passWorldLineEdit->blockSignals(true); //阻止passWorldLineEdit发出信号
passWorldLineEdit->setText(displayText); //用*代替文本内容
passWorldLineEdit->blockSignals(false); //重新启用信号发送
}
}
1.8创建控件样式
|---------|
| 在头文件中声明 |
cpp
void applyStyles(); //控件样式
|-----------|
| .cpp文件中实现 |
cpp
//控件样式
void MainWindow::applyStyles()
{
QString styleSheet =
// ==================== 主窗口全局样式 ====================
"QMainWindow {"
"background-color: #F8F9FA;" // 主背景色(浅灰白),提供干净的背景
"}" // 注意:类名必须严格使用QMainWindow(区分大小写)
// ==================== 标签样式 ====================
"QLabel {"
"color: #495057;" // 文字颜色(深灰色),确保可读性
"font-size: 14px;" // 标准字体大小
"font-weight: 500;" // 中等字重(介于常规和粗体之间)
"padding: 6px 0;" // 垂直内边距(上6px/下6px,左右无)
"}"
// ==================== 输入框基础样式 ====================
"QLineEdit {"
"background-color: #FFFFFF;" // 纯白背景,突出输入区域
"color: #212529;" // 输入文字颜色(接近黑色)
"border: 1px solid #CED4DA;" // 边框颜色(浅灰色)
"border-radius: 6px;" // 6像素圆角,现代感设计
"padding: 8px 12px;" // 内边距(上下8px,左右12px)
"font-size: 14px;" // 输入文字大小
"selection-background-color: #E9ECEF;" // 选中文本背景色(浅灰)
"}"
// ==================== 输入框聚焦状态 ====================
"QLineEdit:focus {" // 当输入框获得焦点时
"border: 2px solid #4DABF7;" // 加粗的蓝色边框(品牌主色)
"background-color: #F8F9FA;" // 背景色变为主背景色,突出焦点
"color: #212529;" // 保持文字颜色不变
"}"
// ==================== 按钮基础样式 ====================
"QPushButton {"
"background-color: #4DABF7;" // 主按钮颜色(品牌蓝)
"color: #FFFFFF;" // 文字白色,高对比度
"border: none;" // 无边框设计
"border-radius: 8px;" // 更大的圆角(8px),柔和外观
"padding: 10px 24px;" // 按钮尺寸(上下10px,左右24px)
"font-size: 14px;" // 按钮文字大小
"font-weight: 600;" // 加粗字体,强调按钮文本
"transition: all 0.3s ease;" // 所有属性变化0.3秒缓动过渡
"box-shadow: 0 2px 4px rgba(0,0,0,0.1);" // 轻微阴影增加层次感
"}"
// ==================== 按钮悬停状态 ====================
"QPushButton:hover {"
"background-color: #339AF0;" // 稍深的蓝色,提供视觉反馈
"box-shadow: 0 4px 6px rgba(0,0,0,0.15);" // 阴影加深
"transform: translateY(-1px);" // 上移1像素,产生悬浮效果
"}" // 注意:transform需要Qt 5.10+
// ==================== 按钮按下状态 ====================
"QPushButton:pressed {"
"background-color: #228BE6;" // 更深的蓝色,模拟按压效果
"box-shadow: 0 1px 2px rgba(0,0,0,0.1);" // 阴影减少
"transform: translateY(0);" // 恢复原位,模拟点击下沉
"}"
// ==================== 按钮禁用状态 ====================
"QPushButton:disabled {" // 禁用状态样式
"background-color: #E9ECEF;" // 浅灰背景
"color: #ADB5BD;" // 灰色文字,表示不可交互
"}";
// 应用样式表到主窗口及其子控件
this->setStyleSheet(styleSheet);
}
2、头文件和.cpp文件
头文件
cpp
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QTimer>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
bool eventFilter(QObject *watched, QEvent *event) override; //事件过滤器
private slots:
void loginButton(); //登录按钮处理的槽函数
void passWorld_startTimer(); //密码定时器处理槽函数
private:
Ui::MainWindow *ui;
// UI 组件
QLabel *accountNumberLabel; //账号标签
QLabel *passWorldLabel; //密码标签
QLineEdit *accountNumberLineEdit; //账号输入框
QLineEdit *passWorldLineEdit; //密码输入框
QPushButton *login_button; //登录按钮
// 密码处理
QTimer *passWorldTimer; //密码定时器
QString visiblePassworld; //真实密码
// 辅助方法
void setWindowGeometry(QWidget *control, int offsetX, int offsetY, int widthW=0, int widthH=0); //设置控件位置和大小
QLabel* createLabel(const QString &text, int offsetX, int offsetY); //创建标签
QLineEdit* createLineEdit(int width, int offsetX, int offsetY); //创建输入框
void createLoginButton(int offsetX, int offsetY); //创建登录按钮
void applyStyles(); //控件样式
};
#endif // MAINWINDOW_H
.cpp文件
cpp
// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QKeyEvent>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, accountNumberLabel(nullptr)
, passWorldLabel(nullptr)
, passWorldTimer(new QTimer(this))
, visiblePassworld("")
{
ui->setupUi(this);
//创建标签
accountNumberLabel = createLabel("账号", 50, 125);
passWorldLabel = createLabel("密码", 50, 80);
//创建输入框
accountNumberLineEdit = createLineEdit(200, 10, 125);
// 密码输入框特殊设置
passWorldLineEdit = createLineEdit(200, 10, 80);
passWorldLineEdit->setEchoMode(QLineEdit::Normal); //设置密码为明文模式
passWorldLineEdit->installEventFilter(this); //安装事件过滤器
//创建登录按钮
createLoginButton(-210, 105);
// 定时器设置
passWorldTimer->setSingleShot(true); //设置定时器单次触发
connect(passWorldTimer, &QTimer::timeout, this, &MainWindow::passWorld_startTimer); //连接定时器结束的信号与槽
// 按钮点击事件
connect(login_button, &QPushButton::clicked, this, &MainWindow::loginButton);
applyStyles();
}
MainWindow::~MainWindow()
{
delete ui;
}
// 事件过滤器实现
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
//检查密码输入框事件是否发生且事件是否为按键按下
if (watched == passWorldLineEdit && event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); //将通用事件对象转换为键盘事件对象
// 处理退格键
if (keyEvent->key() == Qt::Key_Backspace) {
if (!visiblePassworld.isEmpty()) {
visiblePassworld.chop(1); //删除一个字符
// 若密码为空则显示空字符串,否则显示n-1个星号 + 最后一个真实字符
QString displayText = visiblePassworld.isEmpty() ?
"" :
QString(visiblePassworld.length() - 1, '*') + visiblePassworld.right(1);
passWorldLineEdit->blockSignals(true);
passWorldLineEdit->setText(displayText);
passWorldLineEdit->blockSignals(false);
passWorldTimer->start(1000);
}
return true;
}
// 处理普通输入
else if (!keyEvent->text().isEmpty()) {
// 追加新字符到真实密码存储
visiblePassworld += keyEvent->text();
//根据 visiblePassworld 的长度来决定 displayText 的内容
QString displayText = (visiblePassworld.length() > 1) ?
QString(visiblePassworld.length() - 1, '*') + visiblePassworld.right(1) :
visiblePassworld;
passWorldLineEdit->blockSignals(true);
passWorldLineEdit->setText(displayText);
passWorldLineEdit->blockSignals(false);
passWorldTimer->start(1000); //启动定时器
return true;
}
}
// 其他事件交给父类处理
return QMainWindow::eventFilter(watched, event);
}
//控件样式
void MainWindow::applyStyles()
{
QString styleSheet =
// ==================== 主窗口全局样式 ====================
"QMainWindow {"
"background-color: #F8F9FA;" // 主背景色(浅灰白),提供干净的背景
"}" // 注意:类名必须严格使用QMainWindow(区分大小写)
// ==================== 标签样式 ====================
"QLabel {"
"color: #495057;" // 文字颜色(深灰色),确保可读性
"font-size: 14px;" // 标准字体大小
"font-weight: 500;" // 中等字重(介于常规和粗体之间)
"padding: 6px 0;" // 垂直内边距(上6px/下6px,左右无)
"}"
// ==================== 输入框基础样式 ====================
"QLineEdit {"
"background-color: #FFFFFF;" // 纯白背景,突出输入区域
"color: #212529;" // 输入文字颜色(接近黑色)
"border: 1px solid #CED4DA;" // 边框颜色(浅灰色)
"border-radius: 6px;" // 6像素圆角,现代感设计
"padding: 8px 12px;" // 内边距(上下8px,左右12px)
"font-size: 14px;" // 输入文字大小
"selection-background-color: #E9ECEF;" // 选中文本背景色(浅灰)
"}"
// ==================== 输入框聚焦状态 ====================
"QLineEdit:focus {" // 当输入框获得焦点时
"border: 2px solid #4DABF7;" // 加粗的蓝色边框(品牌主色)
"background-color: #F8F9FA;" // 背景色变为主背景色,突出焦点
"color: #212529;" // 保持文字颜色不变
"}"
// ==================== 按钮基础样式 ====================
"QPushButton {"
"background-color: #4DABF7;" // 主按钮颜色(品牌蓝)
"color: #FFFFFF;" // 文字白色,高对比度
"border: none;" // 无边框设计
"border-radius: 8px;" // 更大的圆角(8px),柔和外观
"padding: 10px 24px;" // 按钮尺寸(上下10px,左右24px)
"font-size: 14px;" // 按钮文字大小
"font-weight: 600;" // 加粗字体,强调按钮文本
"transition: all 0.3s ease;" // 所有属性变化0.3秒缓动过渡
"box-shadow: 0 2px 4px rgba(0,0,0,0.1);" // 轻微阴影增加层次感
"}"
// ==================== 按钮悬停状态 ====================
"QPushButton:hover {"
"background-color: #339AF0;" // 稍深的蓝色,提供视觉反馈
"box-shadow: 0 4px 6px rgba(0,0,0,0.15);" // 阴影加深
"transform: translateY(-1px);" // 上移1像素,产生悬浮效果
"}" // 注意:transform需要Qt 5.10+
// ==================== 按钮按下状态 ====================
"QPushButton:pressed {"
"background-color: #228BE6;" // 更深的蓝色,模拟按压效果
"box-shadow: 0 1px 2px rgba(0,0,0,0.1);" // 阴影减少
"transform: translateY(0);" // 恢复原位,模拟点击下沉
"}"
// ==================== 按钮禁用状态 ====================
"QPushButton:disabled {" // 禁用状态样式
"background-color: #E9ECEF;" // 浅灰背景
"color: #ADB5BD;" // 灰色文字,表示不可交互
"}";
// 应用样式表到主窗口及其子控件
this->setStyleSheet(styleSheet);
}
// 定时器处理函数
void MainWindow::passWorld_startTimer()
{
if (!visiblePassworld.isEmpty()) {
QString displayText = QString(visiblePassworld.length(), '*'); //把密码变为*
passWorldLineEdit->blockSignals(true); //阻止passWorldLineEdit发出信号
passWorldLineEdit->setText(displayText); //用*代替文本内容
passWorldLineEdit->blockSignals(false); //重新启用信号发送
}
}
// 登录验证
void MainWindow::loginButton()
{
QString account = accountNumberLineEdit->text();
QString password = visiblePassworld; // 使用存储的真实密码
if (account == "admin" && password == "123456") {
QMessageBox::information(this, "登录成功", "欢迎回来!");
} else {
QMessageBox::warning(this, "登录失败", "账号或密码错误");
}
}
//创建标签
QLabel* MainWindow::createLabel(const QString &text, int offsetX, int offsetY)
{
QLabel *label = new QLabel(text, this);
setWindowGeometry(label, offsetX, offsetY);
return label;
}
//创建输入框
QLineEdit* MainWindow::createLineEdit(int width, int offsetX, int offsetY)
{
QLineEdit *lineEdit = new QLineEdit(this);
setWindowGeometry(lineEdit, offsetX, offsetY, width - lineEdit->width());
return lineEdit;
}
//创建登录按钮
void MainWindow::createLoginButton(int offsetX, int offsetY)
{
login_button = new QPushButton("登录", this);
setWindowGeometry(login_button, offsetX, offsetY, -10, 10);
}
//设置控件位置和大小
/*
control:控件
offsetX:X坐标偏移值
offsetY:Y坐标偏移值
widthW:宽度偏移值
widthH:高度偏移值
*/
void MainWindow::setWindowGeometry(QWidget *control, int offsetX, int offsetY, int widthW, int widthH)
{
int x = (this->width() - control->width()) / 2 - offsetX;
int y = (this->height() - control->height()) / 2 - offsetY;
control->setGeometry(x, y, control->width() + widthW,control->height() + widthH);
}
|--------------------------------------------------------------------------------------------------|
| 总结: 以上就是实现登录界面系统的整个过程了,浏览过程中,如若发现错误,欢迎大 家指正,有问题的可以评论区留言或者私信。最后,如果大家觉得有所帮助的话,可以 点个赞,谢谢大家!祝大家得偿所愿! |
登录系统界面完成!