QT登录系统界面

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);
}

|--------------------------------------------------------------------------------------------------|
| 总结: 以上就是实现登录界面系统的整个过程了,浏览过程中,如若发现错误,欢迎大 家指正,有问题的可以评论区留言或者私信。最后,如果大家觉得有所帮助的话,可以 点个赞,谢谢大家!祝大家得偿所愿! |

登录系统界面完成!

相关推荐
用户805533698033 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner3 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz8 天前
QML Hello World 入门示例
qt
xcyxiner11 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner12 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner12 天前
DicomViewer (添加模型类)3
qt
xcyxiner13 天前
DicomViewer (目录调整) 2
qt
xcyxiner13 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00615 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术15 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript