Qt C++:综合数字图像处理平台–登录界面设计

Qt C++:综合数字图像处理平台–登录界面设计

如何设计一个登陆界面

网络上关于利用Qt设计登录界面的例程很多,实现的复杂度不同功能也相应有所区别。
Qt封装实现了强大的对话框功能(后面有时间专门写一章详细介绍Qt的对话框使用的文章),通常我们使用对话框来实现短期任务和用户交互。在这次的项目中采用一种简单的逻辑实现–QDialog实现。
程序运行后,首先创建一个包含QLabel(文本信息提示)、QLineEdit(用户信息处理)、QCheckBox、QPushButton等一系列功能控件的对话框,在对话框内对相应控件的数据、功能进行处理,实现登录用户的信息验证、新用户注册等功能。由于初次学习使用Qt,登录功能的设计未使用数据库信息存储等高级功能,每个例程只能注册使用一个用户,此外,用户数据的安全性无法保证(从下文的实现代码可以看到)。等后面功力深厚了再做优化吧~

界面设计

登录界面设计如上图所示,QLineEdit实现用户名、密码输入,QCheckBox对是否记住密码进行选择,QPushButton按钮实现注册与登录功能,此外,可以根据自己的需求选择登录界面的背景图。
登录界面的右上角设计为两个QToolButton,实现登录界面的最小化与关闭。由于指定了登录窗口时钟保持置顶显示,最小化按钮未启用。

登录界面各控件命名如上图所示。

代码分析

这部分详细介绍代码实现,部分分析见代码注释。
DialogLogin继承自QDialog,此部分代码为DialogLogin的初始化(构造)与析构函数。

dialoglogin.cpp
//需要用到的相关头文件
#include <QMouseEvent>
#include <QSettings>
#include <QMessageBox>
#include <QByteArray>
#include <QCryptographicHash>
#include <QBitmap>
#include <QPainter>
#include "dialoglogin.h"
#include "ui_dialoglogin.h"
//DialogLogin构造函数
DialogLogin::DialogLogin(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DialogLogin){
    ui->setupUi(this);
    this->setAttribute(Qt::WA_DeleteOnClose);                         //设置该窗口为关闭时删除
    this->setWindowFlags(Qt::SplashScreen|Qt::WindowStaysOnTopHint);  //设置为SplashScreen, 窗口无边框 窗口置顶显示
    QBitmap bmp(this->size());      //创建一张与当前窗口大小一样的位图
    bmp.fill();                     //初始化位图  默认Qt::white
    QPainter p(&bmp);
    p.setPen(Qt::NoPen);
    p.setBrush(Qt::black);          //设置画刷颜色
    p.drawRoundedRect(bmp.rect(),10,10);   //在QBitmap上绘制一个带圆角的区域
    setMask(bmp);                   //设置窗口遮罩 实现登录界面圆角效果
    
    ui->LoginPSWD->setEchoMode(QLineEdit::Password); //设置QLineEdit LoginPSWD为密码输入模式 即输入不可见
    
    ui->ButtLoginClose->setStyleSheet(  //关闭按钮样式表
        "QToolButton{background-color:transparent}" //正常状态下
        "QToolButton:pressed{background-color:red}" //鼠标按下样式
        "QToolButton:hover{background-color:red}"); //鼠标悬停样式
    readSettings();   //读注册表  登陆参数
}
//DialogLogin 析构函数
DialogLogin::~DialogLogin(){
    delete ui;
}

槽函数,注册与登录按钮功能实现

/************************************************************
*函数:on_ButtLOGIN_clicked()
*参数:无
*功能:登陆按钮的槽函数
*返回值:无
*备注:无
************************************************************/
void DialogLogin::on_ButtLOGIN_clicked(){
    QString user=ui->LoginUserName->text().trimmed();  //获取输入用户名
    QString pswd=ui->LoginPSWD->text().trimmed();      //获取输入密码
    if ((user == m_user)&&(pswd == m_pswd)) {          //检查用户名和密码是否正确
        writeSettings();   //保存设置
        this->accept();    //对话框 accept(),关闭对话框
    }
    else{
        m_tryCount++;      //统计错误次数
        if (m_tryCount>3){ //允许连续输错3次密码
            QMessageBox::critical(this, "错误", "输入错误次数太多,强行退出");
            this->reject(); //退出
        }
        else
            QMessageBox::warning(this, "错误提示", "用户名或密码错误");
    }
}
/************************************************************
*函数:on_ButtLoginRegister_clicked()
*参数:无
*功能:注册按钮的槽函数
*返回值:无
*备注:无
************************************************************/
void DialogLogin::on_ButtLoginRegister_clicked(){
    QString NewUser = ui->LoginUserName->text().trimmed();  //获取输入用户名
    QString NewPSWD = ui->LoginPSWD->text().trimmed();      //获取输入密码
    if(QString(NewUser).isEmpty()){       //检查用户名合法性  不为空即可
        QMessageBox::warning(this, tr(""), tr("用户名格式错误   \r\n请重新输入!   "));
    }
    else if(QString(NewPSWD).isEmpty()){  //检查密码合法性
        QMessageBox::warning(this, tr(""), tr("密码格式错误     \r\n请重新输入!   "));
    }
    else{    //用户名密码均无误允许注册 简单注册 只能保存一个账户  新用户会覆盖旧用户
        if(QMessageBox::Yes == QMessageBox::question(this,
                                                      tr(""),
                                                      tr("新的账号密码将会覆盖旧的账户,是否创建?"),
                                                      QMessageBox::Yes | QMessageBox::No,
                                                      QMessageBox::Yes)){
            m_user = NewUser;
            m_pswd = NewPSWD;
            writeSettings();   //保存设置  新账户
            QMessageBox::information(this, tr(""), tr("注册成功!"));
        }
        else{
            QMessageBox::information(this, tr(""), tr("注册失败!"));
        }
    }
}

用户登录数据的读写与校验实现。

/************************************************************
*函数:readSettings()
*参数:无
*功能:读取存储的用户名和密码
*返回值:无
*备注:无
************************************************************/
void DialogLogin::readSettings()
{
    QString organization="Shawn-Qt";//用于注册表,
    QString appName="DIP_Demo";   
    QSettings  settings(organization,appName);//创建
    bool saved=settings.value("saved",false).toBool();   //读取 saved键的值
    m_user=settings.value("Username","User").toString();  //读取 Username 键的值,缺省为“user”
    m_pswd=settings.value("PSWD","12345").toString();     //读取PSWD
    ui->LoginUserName->setText(m_user);
    if(saved){  //如果之前有保存  调用  默认显示旧的账号密码
        ui->LoginPSWD->setText(m_pswd);
    }
    ui->LoginRemb->setChecked(saved);
}
/************************************************************
*函数:writeSettings()
*参数:无
*功能:保存用户名,密码等设置
*返回值:无
*备注:无
************************************************************/
void DialogLogin::writeSettings(){
    QSettings   settings("WWB-Qt","DIP_Demo"); //注册表键组
    settings.setValue("Username",m_user);      //用户名
    settings.setValue("PSWD",m_pswd);          //密码
    settings.setValue("saved",ui->LoginRemb->isChecked());   //记住密码选项保存
}

重载鼠标操作函数实现登录界面鼠标任意点可拖动。

/****************************************************
*函数:mousePressEvent(QMouseEvent *event)
*参数:*event  鼠标事件指针
*功能:重载鼠标点击事件函数 监测鼠标左键按下使能窗口移动
*返回值:无
*备注:该函数在鼠标点击动作下触发
****************************************************/
void DialogLogin::mousePressEvent(QMouseEvent *event){ 
    if (event->button() == Qt::LeftButton){  //如果是左键点击
        m_moving = true;                     //使能窗口移动
        //记录下鼠标相对于窗口的位置
        //event->globalPos()鼠标按下时,鼠标相对于整个屏幕位置
        //pos()->this->pos()鼠标按下时,窗口相对于整个屏幕位置
        m_lastPos = event->globalPos() - pos();
    }
    return QDialog::mousePressEvent(event);
}
/****************************************************
*函数:mouseMoveEvent(QMouseEvent *event)
*参数:*event  鼠标事件指针
*功能:重载鼠标移动事件函数 在移动使能下移动窗口位置
*返回值:无
*备注:该函数在鼠标移动动作下触发
****************************************************/
void DialogLogin::mouseMoveEvent(QMouseEvent *event){
    //(event->buttons() && Qt::LeftButton)按下是左键
    //鼠标移动事件需要移动窗口,窗口移动到哪里呢?就是要获取鼠标移动中,窗口在整个屏幕的坐标,然后move到这个坐标,怎么获取坐标?
    //通过事件event->globalPos()知道鼠标坐标,鼠标坐标减去鼠标相对于窗口位置,就是窗口在整个屏幕的坐标
    if (m_moving && (event->buttons() && Qt::LeftButton)
        && (event->globalPos()-m_lastPos).manhattanLength() > QApplication::startDragDistance()){
        move(event->globalPos()-m_lastPos);
        m_lastPos = event->globalPos() - pos();
    }
    return QDialog::mouseMoveEvent(event);
}
/****************************************************
*函数:mouseReleaseEvent(QMouseEvent *event)
*参数:*event  鼠标事件指针
*功能:重载鼠标按键释放事件函数 失能窗口移动
*返回值:无
*备注:该函数在鼠标按键释放动作下触发
****************************************************/
void DialogLogin::mouseReleaseEvent(QMouseEvent *event){
    event->globalPos();
    m_moving=false;      //停止移动
}

小结

登录界面的制作还是很容易的,可以使用对话框(QDialog)或者直接QWidget,其实本质都是一样的,QDialog也是继承自QWidget,只是QDialog在做登录界面时界面间传递信息方便些(继承类封装了多一些函数,功能指向性强一些而已)。
能力问题,对于注册用户,仅使用了简单的注册表保存数据,安全性没有保障,且只能同时注册使用一个用户,新用户会覆盖就用户的账户密码信息。
个人认为这部分比较有意思的是界面的样式设计,相信你在写一个功能牛逼的软件时是不会给它配上一个Low Low的XP风格界面的。这里只是使用了一个简单的圆角处理,得到一个圆角的登录界面。
详细分析下这段代码,掌握了这种方式可以设计任意形状你想要的牛逼界面。

	QBitmap bmp(this->size());         //创建一张与当前窗口大小一样的位图
    bmp.fill();                        //初始化位图  默认Qt::white
    QPainter p(&bmp);                  //使用QPainter对QBitmap进行绘制
    p.setPen(Qt::NoPen);               //设置相关画图参数
    p.setBrush(Qt::black);             //设置画刷颜色
    //配置完绘制工具  调用你需要的函数对Bitmap 绘制
    p.drawRoundedRect(bmp.rect(),10,10);   //在QBitmap上绘制一个带圆角的区域
    setMask(bmp);                   //设置窗口遮罩 实现登录界面圆角效果

此处对窗口使用setMask函数,即是为窗口添加一个遮罩bmp。
遮罩图片为Black的地方显示窗口内容,White的地方为透明(不显示)。
第2行代码QBitmap.fill函数初始化位图为White。
第5行代码设置QPainter画刷为Black。
第7行代码在与窗口大小相同全为White的Bitmap上绘制了一个黑色的带圆角的区域。
执行setMask函数后便是黑色区域正常显示,其他区域透明显示,实现圆角窗口的效果。
其实这里不一定要是黑色区域,配置画刷为red、green、blue都可以,原因可以去研究setMask的实现 [呲牙]。
总的来说,你需要先绘制好一副你需要的形状的遮罩图形,使用这个图片去对窗口进行遮罩处理即可得到你要的界面。图片可以代码绘制也可以是文件的形式加载,看你需要咯~
参考例程:https://download.csdn.net/download/qq_27131611/10955676

  • 3
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值