项目场景:
客户端界面采用普通账号密码及声纹两种登录方式。其中声纹登录认证模块函数处理大概需要2-4s的延时,造成界面不友好,需要增加等待提示框提示用户。
问题描述
Qt在处理耗时函数时直接增加标签或者加载gif动图,结束耗时函数处理时退出提示框体。无法显示图标及提示语。无法达到想要的实现效果。
原因分析:
提示框体显示的过程中在处理耗时函数无法同步执行框体的事件处理程序,造成图标或文本无法显示。通过下面代码可进行动图及文字的显示,验证图标及文字是否正确加载。但无法继续执行下方处理函数。
m_pWaitingDialog = new WaitingVPPDialog(this);
m_pWaitingDialog->show();
m_pWaitingDialog->exec();
//todo:
//耗时函数代码
解决方案:
通过创建线程在加载等待提示框体的过程中异步处理耗时函数体,耗时函数处理结束时建立信号-槽处理接下来的代码段。
m_pWaitingDialog = new WaitingVPPDialog(this);
m_pWaitingDialog->show();
//异步调用
QFutureWatcher<int> * watcher = new QFutureWatcher<int>;
connect(watcher, &QFutureWatcher<int>::finished,[this,watcher]()
{
int ret = watcher->result();
qDebug() << "futrue:" << ret;
if (ret != 0)
{
qDebug() << "Error: verify, ret = " << ret ;
ret = ISVEDestroyInst(m_inst);
QMessageBox::warning(this,"警告", "声纹登陆失败,请重试!");
return;
}
QString strLoginName;
if(!m_mapUserInfo.isEmpty())
{
QMap<QString, double>::iterator iter;
int nMaxScore = 0;
for(iter = m_mapUserInfo.begin(); iter != m_mapUserInfo.end(); ++iter)
{
if(iter.value() >= nMaxScore)
{
strLoginName = iter.key();
}
}
}
QString strGroup = "";
bool bIsExist = m_sqlSercice.checkVPPLogin(m_strTableName, strLoginName, strGroup);
if(bIsExist && strGroup == "管理员组")
{
this->close();
m_pmanageForm = new ManageForm(true, strLoginName, 0);
m_pmanageForm->move((m_pDesktop->width() - m_pmanageForm->width())/ 2, (m_pDesktop->height() - m_pmanageForm->height()) /2);
m_pmanageForm->show();
}
else if(bIsExist && strGroup != "管理员组")
{
this->close();
m_pmanageForm = new ManageForm(false, strLoginName, 0);
m_pmanageForm->move((m_pDesktop->width() - m_pmanageForm->width())/ 2, (m_pDesktop->height() - m_pmanageForm->height()) /2);
m_pmanageForm->show();
}
else
{
QMessageBox::warning(this,"警告", "声纹识别失败,请重试!");
}
qDebug()<<"result3 完成";
delete watcher;
});
QFuture<int> future = QtConcurrent::run(this,&LoginForm::verify, strPcmPath, fileInfoListModel,
strPass, strXmlPath);
watcher->setFuture(future);
注意:
此处必须通过QFutureWatcher异步监测程序执行结束,通过watcher->result();获取耗时函数的返回值,并做相应的提示框体展示。若通过下方代码仍然造成等待提示框无法加载图片及文字。verify()为声纹验证耗时处理函数。int ret = future.result();
该语句会等待耗时函数处理完后获取返回值,阻塞运行的。
void LoginForm::on_btnLogin_released()
{
if(!m_bLoginWay)
{
//上方代码省略
m_pWaitingDialog = new WaitingVPPDialog(this);
m_pWaitingDialog->show();
QFuture<int> future = QtConcurrent::run(this,&LoginForm::verify, strPcmPath, fileInfoListModel, strPass, strXmlPath);
int ret = future.result();
qDebug() << "futrue:" << ret;
if (ret != 0)
{
qDebug() << "Error: verify, ret = " << ret ;
ret = ISVEDestroyInst(m_inst);
QMessageBox::warning(this,"警告", "声纹登陆失败,请重试!");
return;
}
QString strLoginName;
if(!m_mapUserInfo.isEmpty())
{
QMap<QString, double>::iterator iter;
int nMaxScore = 0;
for(iter = m_mapUserInfo.begin(); iter != m_mapUserInfo.end(); ++iter)
{
if(iter.value() >= nMaxScore)
{
strLoginName = iter.key();
}
}
}
QString strGroup = "";
bool bIsExist = m_sqlSercice.checkVPPLogin(m_strTableName, strLoginName, strGroup);
if(bIsExist && strGroup == "管理员组")
{
this->close();
m_pmanageForm = new ManageForm(true, strLoginName, 0);
m_pmanageForm->move((m_pDesktop->width() - m_pmanageForm->width())/ 2, (m_pDesktop->height() - m_pmanageForm->height()) /2);
m_pmanageForm->show();
}
else if(bIsExist && strGroup != "管理员组")
{
this->close();
m_pmanageForm = new ManageForm(false, strLoginName, 0);
m_pmanageForm->move((m_pDesktop->width() - m_pmanageForm->width())/ 2, (m_pDesktop->height() - m_pmanageForm->height()) /2);
m_pmanageForm->show();
}
else
{
QMessageBox::warning(this,"警告", "声纹识别失败,请重试!");
}
}
效果截图:
部分处理代码下载链接:等待提示框关键代码段
读者需根据实际项目做相应的调整。
本文含有隐藏内容,请 开通VIP 后查看