如何为无法获取进度百分比的耗时操作增加“伪进度条”?

在实际开发中,可能会遇到这样的场景:“一个操作非常耗时,但却无法获取其进度百分比”。造成这种情况的原因可能有: 
1)该操作属于第三方库(泛指我们使用但无法修改的第三方代码,因此质量有高有底),可能由于第三方库作者没有意识到这个操作在某些情况下会非常耗时,没有提供进度值。 
2)某些操作压根就无法计算进度或者计算进度要牺牲极大的效率。

这种场景,执行这样的耗时操作会导致程序UI假死。为了提高用户体验,我们可以为该操作提供一个假的进度条,即保证程序UI不假死。我们将耗时操作放到子线程中去执行,然后在GUI主线程中抛出一个进度对话框,用一个定时器每隔0.5秒(或者一个更合适的值)更新进度条的百分比。用一个循环待子线程执行完毕则GUI主线程继续往下执行。

void MainWindow::slotRun()
{
    QProgressDialog progressDlg(tr("正在读取文件..."), tr("取消"),
                                0, 100, this,
                                Qt::CustomizeWindowHint);
    progressDlg.setWindowModality(Qt::WindowModal);
    progressDlg.setMinimumSize(400, 100);
    progressDlg.show(); // 进度对话框在GUI主线程中执行

    FileReader aFileReader("D:/BigFile.txt");
    FunctionRunThread runThread(aFileReader);  // 将耗时操作放到子线程中去执行
    runThread.start();
    int cnt = 0; // 循环次数计数器,用于"计算"当前的进度值
    while (!runThread.isFinished())  // 只要子线程还没有完成,就一直循环,并更新进度条
    {
        //QThread::currentThread()->wait(500);
        //QApplication::instance()->thread()->wait(500);

        progressDlg.setValue((cnt++%20)*5); // 进度值每次递增5%,达到100后则再次从0开始

        QEventLoop eventloop; // 使用事件循环阻塞主线程
        QTimer::singleShot(500, &eventloop, SLOT(quit())); // wait 0.5s
        eventloop.exec(); // 每0.5秒执行一次事件循环,然后更新进度条
    }
    progressDlg.setValue(100);
    qDebug() << "cnt=" << cnt;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

偶然看到一个更高级的实现方式: 
http://wiki.qt.io/Progress_Bar

http://blog.csdn.net/e5max/article/details/50441148

时间: 2024-08-27 09:15:08

如何为无法获取进度百分比的耗时操作增加“伪进度条”?的相关文章

自定义View之带进度百分比ProgressBar

先上几张自定义所实现的效果图吧,有兴趣的可以继续往下看        实现思路,前四张图呢在自定义progressbar时没有加入text文本,文本是在xml布局时加上去的,最后一张是与progressbar定义在一起的.可以看到有以下几种情况 1,图1自定义中未集成文本的圆环显示,这样的话需要自己添加文本,做法也很简单 利用相对布局,将文本与progressbar进行嵌套,如下:这是整个页面的布局文件,所自定的view为RoundProgressBar <RelativeLayout xmln

097在进度条中显示进度百分比

效果如下: ViewController.h 1 #import <UIKit/UIKit.h> 2 #import "KMProgressViewWithLabel.h" 3 4 @interface ViewController : UIViewController 5 @property (strong, nonatomic) KMProgressViewWithLabel *progressViewCustom; 6 7 @end ViewController.m

progressbar用法:进度画面大小,进度画面背景,进度百分比

前一段时间,由于项目需要研究了下progressbar,发现这个小东西还真是不简单.在这个小控件的显示效果上,花费的时间远大于预估的工作量.话说程序员一直是这样,预估的工作量远少于实际... 先说明一下,这里主要是针对水平进度条进行说明的,关于圆形进度条或者其他进度条可以依此类推.android系统默认的进度条是圆形的,用到水平进度条一般都会加上这样一个属性:"@android:style/Widget.ProgressBar.Horizontal".笔者所发现进度条特殊的地方都是从这

加载页面遮挡耗时操作任务页面--第三方开源--AndroidProgressLayout

在Android的开发中,往往有这种需求,比如一个耗时的操作,联网获取网络图片.内容,数据库耗时读写等等,在此耗时操作过程中,开发者也许不希望用户再进行其他操作(其他操作可能会引起逻辑混乱),而此时需要给用户一个额外的加载页面遮挡住主逻辑代码的运行,待主页面的耗时操作完成后,自动消失这样加载过度页面,恢复出正常应该显示的页面. 举个实际的例子,如代码使用Android WebView打开一个网页链接试图加载某个网站,但网络质量不佳,需要耗时很久,那么在这个过程中,较好的用户体验做法是:给用户一个

主线程中一定不能放耗时操作,必须要开子线程,比如下载文件,不然会不让你拿到输入流--报错显示android.os.NetworkOnMainThreadException

1.必须要开子线程来操作耗时操作,android.os.NetworkOnMainThreadException new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { updateFile = Environment.getExternalStorageDirectory() + "/3530.jpg"; //downloadUpdateFil

finger-guessing game:2增加游戏进度,界面title及游戏界面

增加游戏进度,界面title及游戏界面 //初始化引擎组件 init(50, "div_caiquan", 800, 400, main); //定义游戏层,加载进度层.游戏背景层,结果显示层,出拳操作层 var loadingLayer, backLayer, resultLayer, clickLayer; //定义游戏图片 //定义图片资源加载完成后返回的图片对象 var imglist = {}; //定义图片资源数组 var imgData = new Array( { na

异步委托(APM)使用Func异步操作,处理耗时操作

使用委托进行异步操作,处理一些耗时操作,防止主线程阻塞 使用例子: 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Demo 7 { 8 class Program 9 { 10 11 static void Main(string[] args) 12 { 13 Func<string> fun = new Func<s

sql server 获取每一个类别中值最大的一条数据

sql server 获取每一个类别中值最大的一条数据 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 /* 数据如下: name val memo a    2   a2(a的第二个值) a    1   a1--a的第一个值 a    3   a3:a的第三个值 b    1   b1--b的第一个

模块管理常规功能自定义系统的设计与实现(52--功能更新[2] 对百分比字段的操作)

功能更新(2)  对百分比字段的操作 百分比数据,或者是比率数据是一个比较难处理的字段,难点并不在于单条记录之中,而是在于汇总和分类汇总的时候. 先来看看我系统中的一个模块中的一个比率字段: 上图中的  已支付比例,这个字段是  已支付金额 / 结算金额,这个字段在此合同模块中可以作为一个计算字段来保存在数据库中,甚至可以不保存在数据库中,直接在bean里作为一个计算的属性. 现在问题就来了,如果要计算所有合同的已支付比例,那么就不是简单加起来的问题了,要把分子和分母分别加起来再除才会得到总计的