QT模拟实现网页登录界面

QT模拟实现网页登录界面

常见的网络登录界面一般包括用户名 Lable 和编辑框,密码 Label 和编辑框,是否保存密码的 Check 按钮,以及确定登录和退出按钮组成,界面设计如下:
QT模拟实现网页登录界面_第1张图片
一般的登录流程如下:用户输入用户名和密码,有的可能会勾选保存密码选项;然后点击确定按钮向服务器发出登录请求;服务器收到请求后与数据库中存储的记录比较,存在则允许用户登入系统;客户端在收到确认后先将本次登录计入存入本地文件或数据库,然后开始加载相关内容或服务。
所以在后程序需要模拟服务器验证和用户输入记录缓存的功能。

明白基本流程后,下面介绍一下程序设计。程序界面实现类为QLogInWindow,头文件:

#ifndef QLOGINWINDOW_H
#define QLOGINWINDOW_H

#include 

class QLineEdit;
class QPushButton;
class QCheckBox;

class QLogInWindow : public QMainWindow
{
    Q_OBJECT

public:
    QLogInWindow(QWidget *parent = 0);
    ~QLogInWindow() {}

private:
    void createConnection();//初始化数据库
    bool CheckUser(const QString&, const QString&);//用户校验
    void SaveEntrytoFile(const QString&, const QString&);//保存登录记录到本地

//响应事件
public slots:
    void onOkButtonClicked();
    void onKeyboardButtonPressed();
    void onKeyboardButtonReleased();
    void onPasswdChanged(const QString&);

private:
    QLineEdit *user_entry;//用户名
    QLineEdit *passwd_entry;//密码
    QPushButton* m_EyeButton;//密码显示或隐藏按钮
    QCheckBox *rememberPSW; //是否记住密码
};

#endif // QLOGINWINDOW_H

该类的设计遵循登录界面的基本结构,slot 函数分别对应确定按钮和密码显示控制按钮。
实现:

#include "qloginwindow.h"

// For Debuging
#include <QDebug>
#include <QDate>

#include <QLabel>
#include <QLayout>
#include <QPushButton>
#include <QCheckBox>
#include <QLineEdit>
#include <QMessageBox>
#include <QRegExpValidator>

// For SQL
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlDriver>


QLogInWindow::QLogInWindow(QWidget *parent) : QMainWindow(parent)
{
    QWidget *w = new QWidget(this);
    this->setCentralWidget(w);
    this->setWindowTitle("Log In Demo");

    QGridLayout *grid = new QGridLayout(w);


    user_entry = new QLineEdit(w);
    user_entry->setPlaceholderText("User name");
    passwd_entry = new QLineEdit(w);
    passwd_entry->setPlaceholderText("Password");
    passwd_entry->setEchoMode(QLineEdit::Password);//實現網頁登錄時的眼睛按鈕
    passwd_entry->setContextMenuPolicy(Qt::NoContextMenu);//禁止右鍵菜單

    //密碼顯示或隱藏提示按鈕
    m_EyeButton = new QPushButton();
    m_EyeButton->setObjectName("pEyeButton");
    m_EyeButton->setFixedSize(QSize(16, 16));
    m_EyeButton->setCursor(QCursor(Qt::PointingHandCursor));
    m_EyeButton->setIcon(QIcon(":/Icon/Images/eye-close.png"));
    m_EyeButton->setVisible(false);

    QHBoxLayout* passwordEditLayout = new QHBoxLayout();
    passwordEditLayout->addStretch();
    passwordEditLayout->addWidget(m_EyeButton);
    passwordEditLayout->setSpacing(0);
    passwordEditLayout->setContentsMargins(0, 0, 8, 0);
    passwd_entry->setLayout(passwordEditLayout);

    QRegExp regx("^[^@$%#&^*|/?!~`\'\"]+$");
    if(!regx.isValid()){
        QString str = regx.errorString();
        qDebug() << "Date:" << QDate::currentDate() <<
                    ", Error:" << str;
    }
    QValidator *validator = new QRegExpValidator(regx, passwd_entry);
    passwd_entry->setValidator(validator);//如何模仿 Windows 當輸入包含特殊符號時的提示功能,不能跳过

    grid->addWidget(new QLabel("Username", w), 0, 0, 0);
    grid->addWidget(new QLabel("Password", w), 1, 0, 0);
    grid->addWidget(user_entry, 0, 1, 0);
    grid->addWidget(passwd_entry, 1, 1, 0);

    rememberPSW = new QCheckBox("记住密码", w);
    rememberPSW->setChecked(false);
    grid->addWidget(rememberPSW, 2, 0, Qt::AlignLeft);//是否记忆密码,未实现

    QPushButton *OkButton = new QPushButton("Ok", w);
    grid->addWidget(OkButton, 3, 0, Qt::AlignCenter);
    QPushButton *CancleButton = new QPushButton("Cancle", w);
    grid->addWidget(CancleButton, 3, 1, Qt::AlignCenter);

    OkButton->setDefault(true); //设置默认 OK 按钮选中

    connect(OkButton, SIGNAL(clicked(bool)), this, SLOT(onOkButtonClicked()));
    connect(CancleButton, SIGNAL(clicked(bool)), this, SLOT(close()));
    connect(passwd_entry, SIGNAL(returnPressed()), this, SLOT(onOkButtonClicked()));
    connect(m_EyeButton, SIGNAL(pressed()), this, SLOT(onKeyboardButtonPressed()));
    connect(m_EyeButton, SIGNAL(released()), this, SLOT(onKeyboardButtonReleased()));
    connect(passwd_entry, SIGNAL(textEdited(QString)), this, SLOT(onPasswdChanged(QString)));

    // Init database
    createConnection();
}
void QLogInWindow::createConnection()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(":memory:");
    if (!db.open()) {
        qFatal("Cannot open database");
        return;
    }

    // We store  to query.
    QSqlQuery query;
    query.exec("create table User (name TEXT NOT NULL, passwd TEXT NOT NULL, primary key(name))");

    query.exec("insert into User values('root', 'alpine')");
    query.exec("insert into User values('mobile', 'cherry')");
    return;
}

bool QLogInWindow::CheckUser(const QString &user, const QString &passwd)
{
    QString sql = QString("select name,passwd from User where name='%1' and passwd='%2'").arg(user).arg(passwd);
    qDebug() << sql;
    QSqlQuery query;
    bool ret = query.exec(sql);
    if(!ret) {
        qFatal("Failed to query database");
        return false;
    }

    while (query.next()) {
        qDebug() << "Record found:" << query.value("name").toString() << query.value("passwd").toString();
        return true;
    }

    return false;
}

void QLogInWindow::SaveEntrytoFile(const QString &user, const QString &passwd)
{
    if(rememberPSW->isChecked()) {
        (void)user;
        (void)passwd;
        //将登陆记录存入本地文件,未实现
    }
}

void QLogInWindow::onOkButtonClicked()
{
    QString user = user_entry->text();
    QString passwd = passwd_entry->text();

    if(CheckUser(user, passwd)) {

        int ret = QMessageBox::information(this, "Welcome", "Welcome to Log in",
                                    QMessageBox::Ok);
        switch(ret) {
        case QMessageBox::Ok:
            SaveEntrytoFile(user, passwd);
            close();
        default:
            break;
        }
    } else {
        QMessageBox::warning(this, "Warnning", "User doesn't exist or wrong password",
                                QMessageBox::Ok);
        passwd_entry->selectAll();
    }
}

void QLogInWindow::onPasswdChanged(const QString &text)
{
    if(text.isNull()){
        m_EyeButton->setVisible(false);
    } else {
        m_EyeButton->setVisible(true);
    }
}

void QLogInWindow::onKeyboardButtonPressed()
{
    m_EyeButton->setIcon(QIcon(":/Icon/Images/eye-open.png"));
    passwd_entry->setEchoMode(QLineEdit::Normal);
}

void QLogInWindow::onKeyboardButtonReleased()
{
    m_EyeButton->setIcon(QIcon(":/Icon/Images/eye-close.png"));
    passwd_entry->setEchoMode(QLineEdit::Password);
}

界面布局采用 QGridLayout,界面和数据库的初始化在该类的构造函数中完成,各个响应函数也都大部分完成,这里用两处没有实现:
第一,当用户输入特殊字符,如“@,%,*”,我希望能像 Windows 系统那样弹出提示框。
第二,将登录记录存入本地功能未实现。
另外,在添加数据库模块时,需要修改 pro 文件,在 pro 文件中添加如下内容:

QT       += core gui sql

!contains(sql-drivers, sqlite): QTPLUGIN += qsqlite

关于密码框的眼睛小图标,我直接从 Windows 的登录界面抠的图,希望大家不要见怪。
执行效果:
QT模拟实现网页登录界面_第2张图片
程序不足之处欢迎指点。

参考链接:
Qt 之 模仿 QQ登陆界面——样式篇

正则表达式

QPushButton 响应回车 设置默认按钮

你可能感兴趣的:(qt)