如何diy一款MATLAB进度条?

Posted slandarer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何diy一款MATLAB进度条?相关的知识,希望对你有一定的参考价值。

0效果




1来由

首先我有个程序需要用到进度条,我首先试了一下MATLAB自带的进度条:

bar=waitbar(0,'读取数据中...');    % waitbar显示进度条
for i=1:1000
    A(i)=rand();
    str=['计算中...',num2str(100*i/1000),'%'];   % 显示的文本
    waitbar(i/1000,bar,str)                       
end


但是这样的进度条显得冷冰冰的,我就想研究以下其属性来想办法能否对其修饰,于是我进行了一波 open waitbar 发现这个函数就只是创建了figure和axes并不断更新图像:


其中更新图像主要依赖一个名为 uiwaitbar 的函数:


于是我想当然的试了一下 open uiwaitbar结果发现打不开。。。

于是我根据 waitbar.m 的位置顺藤摸瓜的在:toolbox\\matlab\\uitools\\private
路径找到了 uiwaitbar.p 文件,啊加密文件,那没事了嗷:


虽然是加密文件,但我们还是通过换着参数调用发现这个函数可能需要用到一些png或者css文件:


所以说总结来说waitbar就只是一个不断刷新图像的figure而已,我们自己写的话甚至可以不用css或者png,直接用自带的画图函数都可以。

2函数用法

写了以下几个进度条函数(四种风格):

  • waitBar_SL1.m
  • waitBar_SL2.m
  • waitBar_SL3.m
  • waitBar_SL4.m

基本用法like this:

bar=waitBar_SL1(0,'loading ...');  % 初始化

len=500;
for i=1:len
    A(i)=rand(); % 这句一点用都没有,只是假装这是工程的一部分
    str=['progress - ',num2str(round(i/len*100)),'%']; % 显示的文本
    waitBar_SL1(bar,i/len,str);
end

3完整代码

waitBar_SL1.m


这一版暂不支持中文

function barHdl=waitBar_SL1(varargin)
% @author:slandarer
%
% try this Code:
% --------------------------
% bar=waitBar_SL1(0,'loading ...');  % 初始化
% 
% len=1000;
% for i=1:len
%     A(i)=rand();
%     str=['progress - ',num2str(round(i/len*100)),'%']; % 显示的文本
%     waitBar_SL1(bar,i/len,str);
% end

% 第一次调用先创建figure和axes
if ~strcmp(get(varargin{1},'type'),'figure')
    screenSize=get(0,'ScreenSize');
    width=screenSize(3)*0.24;
    height=screenSize(4)*0.12;
    pos=[screenSize(3)/2-width/2 screenSize(4)/2-height/2 width height];
    barHdl=figure();
    barHdl.Position=pos;
    barHdl.Resize='off';
    barHdl.Name='waitbar-slandarer-type1';
    barHdl.NumberTitle='off';
    barHdl.IntegerHandle='off';
    barHdl.MenuBar='none';
    barHdl.Interruptible='off';
    barHdl.DockControls='off';
    
    barAx=axes('Parent',barHdl);
    barAx.Position=[0 0 1,1];
    barAx.Color=[0.99 0.96 0.95];
    barAx.XColor='none';
    barAx.YColor='none';
    barAx.XLim=[0,105];
    barAx.YLim=[0,60];
    barAx.XGrid='on';
    barAx.YGrid='on';
    barAx.XTick=0:5:105;
    barAx.YTick=0:5:60;
    barAx.GridColor=[0.71 0.78 0.86];
    barAx.GridAlpha=0.3;
    barAx.LineWidth=1.2;
    hold(barAx,'on')
    
    
    rectangle(barAx,'Position',[0 0 105 38],'Curvature',0.3,'FaceColor',[0.4 0.5 1 .2],...
        'LineWidth',1.5,'EdgeColor',[0.16 0.15 0.65],'AlignVertexCenters','on')
    rectangle(barAx,'Position',[2.5 4 100 30],'Curvature',0.1,'FaceColor',[1 1 1 .8],...
        'LineWidth',1.5,'EdgeColor',[0.16 0.15 0.65],'AlignVertexCenters','on')
    barAx.UserData.Title=text(barAx,105/2,50,varargin{2},'horizontalAlignment','center',...
        'FontSize',14,'FontWeight','bold','FontName','Comic Sans MS','Color',[0.16 0.15 0.65]);
    barAx.UserData.RateHdl=plot(barAx,[],[],'Color',[0.16 0.15 0.65],'LineWidth',2,'Tag','rateHdl');
    drawnow
else
    barHdl=varargin{1};
    barAx=barHdl.Children;
    barAx.UserData.Title.String=varargin{3};
    rate=round(varargin{2}*100/5);
    if rate>0
        X=(1:rate).*5;
        Y=ones(1,rate);
        XSet=[X-2.5;X+2.5];
        YSet=[Y.*4.5;Y.*33.5];
        delete(findobj('Tag','rateHdl'));
        barAx.UserData.RateHdl=plot(barAx,XSet,YSet,'Color',[0.16 0.15 0.65],'LineWidth',2,'Tag','rateHdl');
    end
    drawnow
end
    
    
end

waitBar_SL2.m

function barHdl=waitBar_SL2(varargin)
% @author:slandarer
%
% try this Code:
% --------------------------
% bar=waitBar_SL2(0,'loading ...');  % 初始化
% 
% len=1000;
% for i=1:len
%     A(i)=rand();
%     str=['progress - ',num2str(round(i/len*100)),'%']; % 显示的文本
%     waitBar_SL2(bar,i/len,str);
% end

xyMin=[5,10];
xyMax=[95,25];
% 第一次调用先创建figure和axes
if ~strcmp(get(varargin{1},'type'),'figure')
    screenSize=get(0,'ScreenSize');
    width=screenSize(3)*0.24;
    height=screenSize(4)*0.12;
    pos=[screenSize(3)/2-width/2 screenSize(4)/2-height/2 width height];
    barHdl=figure();
    barHdl.Position=pos;
    barHdl.Resize='off';
    barHdl.Name='waitbar-slandarer-type2';
    barHdl.NumberTitle='off';
    barHdl.IntegerHandle='off';
    barHdl.MenuBar='none';
    barHdl.Interruptible='off';
    barHdl.DockControls='off';
    
    barAx=axes('Parent',barHdl);
    barAx.Position=[0 0 1,1];
    barAx.Color=[0.99 0.96 0.95];
    barAx.XColor='none';
    barAx.YColor='none';
    barAx.XLim=[0,100];
    barAx.YLim=[0,50];
    hold(barAx,'on')
    
    
    fill(barAx,[xyMin(1),xyMax(1),xyMax(1),xyMin(1)],...
               [xyMin(2),xyMin(2),xyMax(2),xyMax(2)],[0.85 0.4 0.13].*1.1);
    xSep1=5;
    xSep2=3;
    for i=1:9
        fill(barAx,[xyMin(1),xyMin(1)+xSep1,xyMin(1)+xSep1+xSep2,xyMin(1)+xSep2]+(i-1)*10.2,...
                   [xyMin(2),xyMin(2),xyMax(2),xyMax(2)],[0.82 0.33 0.12],'EdgeColor','none')
    end
    
    barAx.UserData.Title=text(barAx,5,37.5,varargin{2},'horizontalAlignment','left',...
        'FontSize',14,'FontWeight','bold','Color',[0.2 0.2 0.2]);
    barAx.UserData.RateHdl=fill(barAx,[xyMin(1),xyMax(1),xyMax(1),xyMin(1)],...
                                      [xyMin(2),xyMin(2),xyMax(2),xyMax(2)],...
                                      [0.99 0.96 0.95],'EdgeColor','none');
    plot(barAx,[xyMin(1),xyMin(1)]-0.8,[xyMin(2),xyMax(2)],'Color',[0.2,0.2,0.2],'LineWidth',3)
    plot(barAx,[xyMax(1),xyMax(1)]+0.8,[xyMin(2),xyMax(2)],'Color',[0.2,0.2,0.2],'LineWidth',3)
    plot(barAx,[xyMin(1),xyMax(1)],[xyMin(2),xyMin(2)]-1,'Color',[0.2,0.2,0.2],'LineWidth',3)
    plot(barAx,[xyMin(1),xyMax(1)],[xyMax(2),xyMax(2)]+1,'Color',[0.2,0.2,0.2],'LineWidth',3)
    drawnow
else
    barHdl=varargin{1};
    barAx=barHdl.Children;
    barAx.UserData.Title.String=varargin{3};
    rate=varargin{2};
    xMin=rate*(xyMax(1)-xyMin(1))+xyMin(1);
    barAx.UserData.RateHdl.XData=[xMin,xyMax(1),xyMax(1),xMin];
    drawnow
end

waitBar_SL3.m

function barHdl=waitBar_SL3(varargin)
% @author:slandarer
%
% 以上是关于如何diy一款MATLAB进度条?的主要内容,如果未能解决你的问题,请参考以下文章

当片段视图加载是异步任务的一部分时,如何在片段加载之前显示进度条?

自定义对话框片段内的进度条 - 如何从 AsyncTask 传递进度?

如何将进度条控件添加到 Matlab gui?

活动到片段方法调用带有进度条的线程

如何使用 asynctask 执行数据库操作来实现进度条?

如何重新加载圆形进度条