一、Splash窗口
- 什么是Splash窗口?一般在大型应用程序启动时会显示一个启动画面,这个启动画面即Splash窗口
- 特点:Splash窗口一般被设计为一个无边对话框,在Windows任务栏不显示当前窗口的图标信息。
- 我们通常在Splash窗口中只显示一个图片,并展示软件的信息等
- 使用场景:Splash窗口显示的时候,程序一般在后台做一些比较耗时的启动准备工作,等到软件的准备工作完成之后,Splash窗口就会关闭,然后软件的主窗口显示出来
- QSplashScreen类:此类就是实现Splash窗口的,它提供了载入图片,自动设置窗口无边框效果等功能
如何设置Splash窗口:
- 在构造函数中使用setWindowFlags函数,参数为Qt::SplashScreen
- 设置完成之后,窗体就变为无边框,在Windows任务栏不显示当前窗口的图标信息
备注:如果想要窗体无边框,但在Windows任务栏显示当前窗口的图标信息,就使用下面函数
二、登录窗口
- 有的应用程序在使用的时候,需要输入用户名和密码才可以进入软件
三、演示案例
- 下面我们将Splash窗口与登录窗口做一个合并,做一个登录界面
窗体设计:
- 主窗体创建好之后,我们再创建一个对话框,类名为QDlgLogin,这个类就是我们的Splash窗口与登录窗口
- 将窗体的取消按钮clicked()信号与窗体的reject()槽函数相关联
构造函数
- setWindowFlags函数:将当前窗口设置为Splash模式,无边框,在Windows任务栏显示标题
QDlgLogin::QDlgLogin(QWidget *parent) : QDialog(parent), ui(new Ui::QDlgLogin) { ui->setupUi(this); ui->editPSWD->setEchoMode(QLineEdit::Password); //设置密码编辑框输入模式为密码输入模式 this->setAttribute(Qt::WA_DeleteOnClose); //当前窗体关闭时窗体对象删除 this->setWindowFlags(Qt::SplashScreen); //当前窗体设置为SplashScreen格式,无边框,在Windows任务栏不显示标题 //this->setWindowFlags(Qt::FramelessWindowHint); //当前窗体无边框,但在Windows任务栏显示标题 QPixmap mImage = QPixmap(":/pictures/timg.jpg");//加载图片 ui->label->setPixmap(mImage); readSettings(); //读取存储的用户名和密码 }
readSettings、writeSettings函数
- readSettings函数用来读取注册表中的用户名和密码,密码是经过加密的
- writeSettings函数用于保存用户名和密码到注册表中
- QSettings类详情,见文章:https://blog.csdn.net/qq_41453285/article/details/99591318
void QDlgLogin::readSettings() { QString organization="WWB-Qt"; //注册表 QString appName="samp6_5"; QSettings settings(organization,appName); //打开一个QSettings对象 bool saved=settings.value("saved",false).toBool(); //读取saved键,并判断返回是否存在saved键,缺省值为flase m_user=settings.value("Username","user").toString();//读取Username键的值,缺省值为user QString defaultPSWD=encrypt("12345"); //默认的密码(加密过的) m_pswd=settings.value("PSWD",defaultPSWD).toString();//读取PSWD键的值,缺省值为defaultPSWD if(saved) //如果saved有键,就将Username显示在editUser控件中 ui->editUser->setText(m_user); ui->chkBoxSave->setChecked(saved); //设置当前是否保存用户名 }
void QDlgLogin::writeSettings() { QSettings settings("WWB-Qt","samp6_5");//打开一个QSettings对象 settings.setValue("Username",m_user); //将m_user设置为Username键的值 settings.setValue("PSWD",m_pswd);//将m_pswd设置为PSWD键的值 settings.setValue("saved",ui->chkBoxSave->isChecked());//将chkBoxSave的选择结果设置为saved键的值 }
encrypt函数
- 此函数的参数为未加密的密码字符串,进过MD5加密后返回加密后的字符串
QString QDlgLogin::encrypt(const QString &str) { //将传入进来的密码字符串转换为字节数组,因为加密算法需要字节对象 QByteArray btArray; btArray.append(str); //指定MD5加密算法的QCryptographicHash对象 QCryptographicHash hash(QCryptographicHash::Md5); hash.addData(btArray); //将btArray作为参数加密 QByteArray resultArray=hash.result();//得到hash加密后的结果 QString md5=resultArray.toHex(); //将字节数组内容转换为字符串 return md5; //返回加密后的密码 }
确定按钮的clicked函数
- 当点击确定按钮时,判断是否正确并登录到主窗口
- 由于QCryptographicHash对象只提供了加密功能,没有提供解密功能,所以判断的时候我们只能使用加密后的密码进行判断
void QDlgLogin::on_btnOK_clicked() { QString user=ui->editUser->text().trimmed();//得到输入的用户名 QString pswd=ui->editPSWD->text().trimmed();//得到输入的密码 QString encrptPSWD=encrypt(pswd);//将输入的密码进行MD5加密 //如果账户名和密码都正确 if((user==m_user)&&(encrptPSWD==m_pswd)) { writeSettings();//将用户名和密码写入注册表 this->accept();//对话框关闭 } else//如果输入错误 { m_tryCount++; if(m_tryCount>3)//错误次数大于3次,直接退出 { QMessageBox::critical(this,QStringLiteral("错误"), QStringLiteral("输入错误次数过多")); this->reject(); //窗体退出 } else//错误次数小于等于3次,只提示不退出 QMessageBox::critical(this,QStringLiteral("错误提示"), QStringLiteral("用户名或密码错误")); } }
鼠标按下、移动、松开事件函数
- mousePressEvent:鼠标左键按下时记录下当前鼠标的坐标
- mouseMoveEvent:鼠标左键按下开始移动
- mouseReleaseEvent:鼠标左键松开时
void QDlgLogin::mousePressEvent(QMouseEvent *event) { //如果是鼠标左键按下 if(event->button()==Qt::LeftButton) { m_moving=true; //当前窗口被鼠标单击选中 m_lastPos=event->globalPos()-pos();//记录下鼠标相对于当前窗口的位置 } return QDialog::mouseMoveEvent(event); }
void QDlgLogin::mouseMoveEvent(QMouseEvent *event) { //当前窗口被选中&&鼠标左键被按下&&鼠标移动的位置大于鼠标一开始选中的位置 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); }
void QDlgLogin::mouseReleaseEvent(QMouseEvent *event) { m_moving=false; //当前鼠标没有按下并且不移动 }
Splash窗口与登录窗口的调用
- 因为设计的Splash登录窗口要在主窗口之前被调用,所以我们需要更改一下main函数
- 窗体以模式显示的方式调用对话框(exec),如果对话框返回的结果是QDialog::Accepted,说明对话框执行成功