在Qt开发中经常会使用到一个等待界面,很巧,这周开发就遇到了,思索了半天,还是问问度娘,网上的答案很乱。浅浅记录一下
首先我制作了一个按钮,按下按钮的时候会有一个弹窗选择,如果选择“YES”就往下执行等待画面,在等待中我得在Linux下打包指定的文件到指定目录。这里我用的是QProcess来操作。
打包用到的命令:tar -czf 路径/文件名.tgz 目标文件
现在我们来制作一个简单的UI界面
UI制作Ok,只需要把gif图片Setmovie到QLabel上就行,封装起来随时调用。
QMovie *pMovie = new QMovie(":/image/Image/loading.gif");
ui->loadingLab->setFixedSize(50, 50);//调整大小放进Gif
ui->loadingLab->setScaledContents(true);//自适应窗口大小
ui->loadingLab->setMovie(pMovie);//将动画设置到QLabel中
pMovie->start();//启动
setWindowModality(Qt::ApplicationModal);//模态化
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);//设置顶部弹出
UI弄好了,接着就是使用QProcess了,先看一下说明
QProcess类提供了三个函数
1、QProcess::execute() 以堵塞方式的执行shell命令,当命令执行完成后,调用进程才会继续执行。命令输出的任何数据都将转发给调用进程输出(因此无法捕获)。
2、QProcess::start() 以异步方式的执行shell命令,命令输出的数据存储于缓冲区,可以通过readAllStandardOutput()捕获
3、QProcess::startDetached() 以分离的方式执行shell命令,调用进程退出,则分离的进程将继续运行,而不受影响。
我用的第二种:QProcess::start()
补:因为打包规定的文件名需要加上实时时间,所以多写了两行。代码如下:
QProcess *process = new QProcess();
QStringList args;
QDateTime current_date_time =QDateTime::currentDateTime();//获取当前时间
QString current_date =current_date_time.toString("yyyyMMdd_hh:mm");//转换QString格式
QString FileName = "BHM100_"+current_date;//规定名+时间
QString FilePath = "/存放路径" +FileName +".tgz";//存放路径+文件名
QString Target = "Test/";//目标文件
args << "-czf"<< FilePath << Target;
qDebug()<<"args"<<args;
process->setWorkingDirectory("/文件名");//设置工作目录在/文件名下
process->start("tar",args);//非阻塞
process->close();
接着我想直接加上等待画面,很简单。但是好像又没有等待过程,画面一闪而过,于是又找QProcess方法,找到了等待该进程完成的方法。
QProcess执行命令时都会执行
waitForFinished
等待程序执行完成,默认超时时间30s。设置
waitForFinished(-1)
参数(直到执行完成)。
QProcess *process = new QProcess();
QStringList args;
QDateTime current_date_time =QDateTime::currentDateTime();//获取当前时间
QString current_date =current_date_time.toString("yyyyMMdd_hh:mm");//转换QString格式
QString FileName = "BHM100_"+current_date;//规定名+时间
QString FilePath = "/存放路径" +FileName +".tgz";//存放路径+文件名
QString Target = "Test/";//目标文件
args << "-czf"<< FilePath << Target;
qDebug()<<"args"<<args;
process->setWorkingDirectory("/文件名");//设置工作目录在/文件名下
process->start("tar",args);//非阻塞
//===========================================================
if (!process->waitForFinished(-1))//等待程序结束完毕。设置msecs为-1,直到运行完毕。
{
process->close();
//qDebug()<<"备份失败";
return;
}
//==============================================================
process->close();
这时候把等待界面放在process->start后显示是不是就完成了?
答:是的(如果不在一个线程的话)
LoadingDia* loadingdia = new LoadingDia();//生成等待界面
loadingdia->show();
......
//===========================================================
if (!process->waitForFinished(-1))//等待程序结束完毕。设置msecs为-1,直到运行完毕。
{
process->close();
//qDebug()<<"备份失败";
return;
}
//==============================================================
process->close();
loadingdia->close();
但是跑起来的时候,运行到process->waitForFinished(-1)就卡死了,等待画面也出不来,啥也干不了。但是还能成功打包O_o,头大了,又问了度娘,process->
waitForFinished()在没有完成之前会一直阻塞在那里,这
好像是放在一个线程造成的原因。接着又使用QFutrue在一个单独的线程中调用QProcess成功解决问题。
QFuture<void> res = QtConcurrent::run(this, &BackUpsWidget::Backup_Process);//启动线程调用
while(!res.isFinished())
{
//
QApplication::processEvents();//不停地处理事件,让程序保持响应
}
ok,测试了一下,没问题。具体代码放下面
void BackUpsWidget::Backup_Process()
{
QProcess *process = new QProcess();
QStringList args;
QDateTime current_date_time =QDateTime::currentDateTime();//获取当前时间
QString current_date =current_date_time.toString("yyyyMMdd_hh:mm");//转换QString格式
QString FileName = "BHM100_"+current_date;//规定名+时间
QString FilePath = "/存放路径" +FileName +".tgz";//存放路径+文件名
QString Target = "Test/";//目标文件
args << "-czf"<< FilePath << Target;
qDebug()<<"args"<<args;
process->setWorkingDirectory("/文件名");//设置工作目录在/文件名下
process->start("tar",args);//非阻塞
//===========================================================
if (!process->waitForFinished(-1))//等待程序结束完毕。设置msecs为-1,直到运行完毕。
{
process->close();
//qDebug()<<"备份失败";
return;
}
//==============================================================
process->close();
}
void BackUpsWidget::_BackButtonClick()
{
LoadingDia* loadingdia = new LoadingDia();//生成等待界面
loadingdia->show();
QFuture<void> res = QtConcurrent::run(this, &BackUpsWidget::Backup_Process);//启动线程调用
while(!res.isFinished())
{
//
QApplication::processEvents();//不停地处理事件,让程序保持响应
}
loadingdia->closse();
}
2023新年快乐
版权归原作者 Sumoran14 所有, 如有侵权,请联系我们删除。