草庐IT

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

Sumoran14 2025-02-11 原文

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

有关QtUI界面被QProcess阻塞(已解决)的更多相关文章

  1. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

  2. 【高数】用拉格朗日中值定理解决极限问题 - 2

    首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有,  也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加

  3. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  4. ruby - 如何更快地解决 project euler #21? - 2

    原始问题Letd(n)bedefinedasthesumofproperdivisorsofn(numberslessthannwhichdivideevenlyinton).Ifd(a)=bandd(b)=a,whereab,thenaandbareanamicablepairandeachofaandbarecalledamicablenumbers.Forexample,theproperdivisorsof220are1,2,4,5,10,11,20,22,44,55and110;therefored(220)=284.Theproperdivisorsof284are1,2,

  5. ruby - 为什么这些方法没有解决? - 2

    这个问题在这里已经有了答案:WhydoRubysettersneed"self."qualificationwithintheclass?(3个答案)关闭29天前。给定这段代码:classSomethingattr_accessor:my_variabledefinitialize@my_variable=0enddeffoomy_variable=my_variable+3endends=Something.news.foo我收到这个错误:test.rb:9:in`foo':undefinedmethod`+'fornil:NilClass(NoMethodError)fromtes

  6. 电脑启动后显示器黑屏怎么办?排查下面4个问题,快速解决 - 2

    电脑启动出现显示器黑屏是一个相当常见的问题。如果您遇到了这个问题,不要惊慌,因为它有很多可能的原因,可以采取一些简单的措施来解决它。在本文中,小编将介绍下面4种常见的电脑启动后显示器黑屏的原因,排查这些原因,快速解决! 演示机型:联想Ideapad700-15ISK-ISE系统版本:Windows10一、显示器问题如果出现电脑启动后显示器黑屏的情况。那么首先您需要检查一下显示器是否正常工作。您可以通过更换另一个显示器或将当前显示器连接到另一台计算机来检查显示器是否存在问题。如果问题仍然存在,那么您可以排除显示器故障的可能性。 二、显卡问题如果您的电脑配备了独立显卡,那么显卡故障也可能是导致电脑

  7. 关于Qt程序打包后运行库依赖的常见问题分析及解决方法 - 2

    目录一.大致如下常见问题:(1)找不到程序所依赖的Qt库version`Qt_5'notfound(requiredby(2)CouldnotLoadtheQtplatformplugin"xcb"in""eventhoughitwasfound(3)打包到在不同的linux系统下,或者打包到高版本的相同系统下,运行程序时,直接提示段错误即segmentationfault,或者Illegalinstruction(coredumped)非法指令(4)ldd应用程序或者库,查看运行所依赖的库时,直接报段错误二.问题逐个分析,得出解决方法:(1)找不到程序所依赖的Qt库version`Qt_5'

  8. 【RuntimeError: CUDA error: device-side assert triggered】问题与解决 - 2

    RuntimeError:CUDAerror:device-sideasserttriggered问题描述解决思路发现问题:总结问题描述当我在调试模型的时候,出现了如下的问题/opt/conda/conda-bld/pytorch_1656352465323/work/aten/src/ATen/native/cuda/IndexKernel.cu:91:operator():block:[5,0,0],thread:[63,0,0]Assertion`index>=-sizes[i]&&index通过提示信息可以知道是个数组越界的问题。但是如图一中第二行话所说这个问题可能并不出在提示的代码段

  9. ruby-on-rails - 如何解决#<Book::ActiveRecord_Relation:0x007fb709a6a8c0> 的未定义方法 `to_key'? - 2

    我遇到了未定义方法`to_key'的问题这是我的books_controller.rbclassBooksController和我的索引页如下。index.html.erb......现在当我要访问索引页面时出现如下错误。undefinedmethod`to_key'for# 最佳答案 index通常返回一个集合。事实上,您的Controller符合要求。但是,您的View试图为其定义一个表单。正如您所发现的,这不会成功。表单适用于实体,而不适用于集合。该错误在您看来以及您希望如何处理index。

  10. ruby-on-rails - 本地 gem 的“bundle 安装”没有解决依赖关系,而 'gem install' 可以 - 2

    我在目录“/home/enterprise/pkg”中有一个本地gem(enterprise-0.0.1.gem)。它依赖于active_directorygem(v1.5.5),这是在它的enterprise.gemspec文件中指定的,如下所示:-gem.add_dependency("active_directory")在我的应用程序的Gemfile中,我添加了以下行:-gem'enterprise','0.0.1',path=>'/home/enterprise/pkg'当我做的时候bundleinstall在我的应用程序的源目录中,只安装了企业gem。因此,我遇到了引用act

随机推荐