QT模擬實現網頁登錄界面

QT模擬實現網頁登錄界面

常見的網絡登錄界面一般包括用戶名 Lable 和編輯框,密碼 Label 和編輯框,是否保存密碼的 Check 按鈕,以及確定登錄和退出按鈕組成,界面設計如下:
這裏寫圖片描述
一般的登錄流程如下:用戶輸入用戶名和密碼,有的可能會勾選保存密碼選項;然後點擊確定按鈕向服務器發出登錄請求;服務器收到請求後與數據庫中存儲的記錄比較,存在則允許用戶登入系統;客戶端在收到確認後先將本次登錄計入存入本地文件或數據庫,然後開始加載相關內容或服務。
所以在後程序需要模擬服務器驗證和用戶輸入記錄緩存的功能。

明白基本流程後,下面介紹一下程序設計。程序界面實現類爲QLogInWindow,頭文件:

#ifndef QLOGINWINDOW_H
#define QLOGINWINDOW_H

#include <QMainWindow>

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 <user,passwd> 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 之 模仿 QQ登陸界面——樣式篇

正則表達式

QPushButton 響應回車 設置默認按鈕

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章