Dawn
Dawn

Reputation: 3628

How to add progress bar control to Matlab gui?

Is there a ready made progress bar uicontrol that can be added to Matlab gui, either uicontrol or ActiveX component?

[edit] I know about the waitbar function, I meant a component that can be implemented into the designed GUI and not just pop out of the window. Something like battery status in status bar.

Upvotes: 18

Views: 32885

Answers (7)

pattivacek
pattivacek

Reputation: 5823

For anyone still interested, here's my solution using a class:

classdef progressbar < handle
    properties(Access = protected)
        h_panel         % Panel on which everything sits
        h_ax            % The progress range axes
        h_pbar          % The bar representing progress (patch)
        h_ptext         % Percentage label
    end
    properties(Access = public, Dependent = true)
        range           % Progress range
        pvalue          % Current value
        percent         % Percentage complete (relative within range)
        position        % Position of the object (panel)
        ax_tag          % Tag of the axes
        visible         % Is the object (panel) visible?
    end
    properties(Constant = true)
        default_color = [.75 .75 .9];
    end
    methods
        % Initializer
        function obj = progressbar(fig, pos, range)
            if nargin < 3
                range = [0 1];
            end
            obj.h_panel = uipanel('Parent', fig, 'Units', 'Inches', ...
                'Position', pos, 'Tag', 'progbar_panel');
            obj.h_ax = axes('Parent', obj.h_panel, ...
                'Units', 'Inches', 'Position', [0 0 obj.position(3) obj.position(4)], ...
                'XTickLabel', '', 'XTick', [], 'YTickLabel', '', 'YTick', []);
            obj.h_pbar = patch([range(1) range(1) range(1) range(1)], [0 0 2 2], ...
                obj.default_color, 'Parent', obj.h_ax, 'Tag', 'progbar_patch');
            obj.h_ptext = text(obj.position(3)/2, obj.position(4)/2, '0%', ...
                'Parent', obj.h_ax, 'FontWeight', 'bold', 'Units', 'Inches', ...
                'HorizontalAlignment', 'center', 'Tag', 'progbar_text');
            obj.range = range;
            obj.ax_tag = 'progbar_ax';
        end

        % Property Access Methods
        function set.range(obj, value)
            % Instead of replotting, just reset the XLim to the
            % extremities of the input range. If the values are not
            % increasing, just default to [0 1].
            if value(end) > value(1)
                set(obj.h_ax, 'XLim', value([1,end]), 'YLim', [0 2]);
            else
                set(obj.h_ax, 'XLim', [0 1], 'YLim', [0 2]);
            end
            % Reset progress.
            obj.pvalue = value(1);
        end
        function value = get.range(obj)
            value = get(obj.h_ax, 'XLim');
        end
        function set.pvalue(obj, value)
            % Expects a single value to represent progress value and
            % constructs the selection rectangle from that. If multiple
            % values are passed in, all are ignored but the last, since the
            % left edge of the bar is always the first element of the
            % range.
            set(obj.h_pbar, 'XData', [obj.range(1) value(end) value(end) obj.range(1)], ...
                'FaceColor', obj.default_color);
            set(obj.h_ptext, 'String', sprintf('%3.0f%%', obj.percent * 100));
        end
        function value = get.pvalue(obj)
            % The progress bar is actually 2D, but we treat as if it is 1D.
            % Hence the XData is actually an array of four values but we
            % only consider the second (progress maximum).
            limits = get(obj.h_pbar, 'XData');
            value = limits(2);
        end
        function set.percent(obj, value)
            % Expects a single value between 0 and 1.
            limits = obj.range;
            obj.pvalue = value * (limits(2) - limits(1)) + limits(1);
        end
        function value = get.percent(obj)
            limits = obj.range;
            value = (obj.pvalue - limits(1)) / (limits(2) - limits(1));
        end
        function set.position(obj, value)
            set(obj.h_panel, 'Position', value);
        end
        function value = get.position(obj)
            value = get(obj.h_panel, 'Position');
        end
        function set.ax_tag(obj, value)
            set(obj.h_ax, 'Tag', value);
        end
        function value = get.ax_tag(obj)
            value = get(obj.h_ax, 'Tag');
        end
        function set.visible(obj, value)
            if (isnumeric(value) && value >= 1) || strcmp(value, 'on') == 1 || strcmp(value, 'On') == 1
                set(obj.h_panel, 'Visible', 'on');
            else
                set(obj.h_panel, 'Visible', 'off');
            end
        end
        function value = get.visible(obj)
            vis = get(obj.h_panel, 'Visible');
            value = strcmp(vis, 'on');
        end

        % Public member functions
        function increment(obj)
            % Don't use this if the range is less than 1.
            obj.pvalue = obj.pvalue + 1;
        end
        function display_text(obj, text, color)
            if nargin == 3 && ~isempty(color)
                set(obj.h_pbar, 'FaceColor', color);
            end
            set(obj.h_ptext, 'String', text);
        end
    end
end

Declare an instance like so: pb = progressbar(gcf, [1 1], [0 20]);

It can be used with relative or actual numbers, i.e. pb.pvalue = 10; and pb.percent = .5; do the same thing in my example.

My version features a text object in the middle of the progress bar that displays the current percentage.

My latest version is available here.

Upvotes: 2

Blade20004
Blade20004

Reputation: 1

There is another way... Sorry if it was mentioned and I missed it. You can build a figure dynamicly adding the axes for a bar.. It works very nicely and easly adaptable for custom applications. Pop ups were always getting lost or in the way.

Upvotes: -1

Marks
Marks

Reputation: 31

another simple solution is to use two nested uipanels like this:

function MyProgressBar(handle, progress)
   % progress = 0.00001 .... 1

   % 1st panel
   p = uipanel(handle);

   % 2n panel as bar
   bar = uipanel(p);
    set(bar, 'BackgroundColor', 'red');
    x = get(bar, 'Position');
    x(3) = progress;       % Corresponds to % progress if unit = normalized
    set(bar, 'Position',x);
end

Usage:

 f = figure();
 set(f,'Position',[100,100,400,40]);
 MyProgressBar(f, 0.5); % corresponds to 50% progress

Upvotes: 3

James Mertz
James Mertz

Reputation: 8759

Adapting my code from this MatLab Newgroup comment, I was able to put together the following:

function h = uiProgressBar(varargin)
%uiProgressBar: A waitbar that can be embedded in a GUI figure.

    if ishandle(varargin{1}) && size(varargin, 2) > 1
        ax = varargin{1};
        value = varargin{2};
        p = get(ax,'Child');
        x = get(p,'XData');
        x(3:4) = value;
        set(p,'XData',x)
        return
    end

    bg_color = 'w';
    fg_color = 'r';
    h = axes('Units','pixels',...
        'XLim',[0 1],'YLim',[0 1],...
        'XTick',[],'YTick',[],...
        'Color',bg_color,...
        'XColor',bg_color,'YColor',bg_color, ...
        'Parent', varargin{1});
    patch([0 0 0 0],[0 1 1 0],fg_color,...
        'Parent',h,...
        'EdgeColor','none',...
        'EraseMode','none');
end

Creation is as follows, where parent is the parent panel that you want to add it to:

myProgressBar = uiProgressBar(parent);

and updating the progress bar is as simple as this:

uiProgressBar(myProgressBar, .2);

Here's a full working example using a figure:

f = figure('Name', 'Progress Bar Example', 'Position', [100 100 800 600]);

progressBar = uiProgressBar(f);

for i = 1:10:100
    uiProgressBar(progressBar, i/100);
    pause(.5);
end

ProgressBarLook

Upvotes: 4

magarwal
magarwal

Reputation: 574

Matlab has inbuilt 'waitbar'... you may also any of these tools from matlab site:

http://www.mathworks.com/matlabcentral/fileexchange/26773-progress-bar&watching=26773

http://www.mathworks.com/matlabcentral/fileexchange/3607-progressbar

Upvotes: 1

Yair Altman
Yair Altman

Reputation: 5722

Waitbar and its variants display a popup window with a status bar. In most applications this is ok and very simple to use.

If you want to integrate a progress-bar within an existing GUI window, you have several choices:

  1. implement the internal waitbar code - this is really just an axes that presents a colored patch whose width depends on the progress value.
  2. use the standard java.swing.JProgressBar, which can be added to your Matlab GUI via the built-in javacomponent function
  3. use the StatusBar utility or the explanation here to add a progress bar to your GUI window's status-bar

All of these choices work on all Matlab platforms.

Upvotes: 28

abcd
abcd

Reputation: 42225

Yes, there is. The waitbar function is what you need. The examples there are easy to follow and you can get started right away. It should work fine on all 3 platforms (Windows/OS X/Linux).

Upvotes: 6

Related Questions