0


QtUI界面被QProcess阻塞(已解决)

在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新年快乐

标签: qt ui 开发语言

本文转载自: https://blog.csdn.net/Sumoran14/article/details/128609083
版权归原作者 Sumoran14 所有, 如有侵权,请联系我们删除。

“QtUI界面被QProcess阻塞(已解决)”的评论:

还没有评论