Extending MATLAB uicontrol

2019-07-15 17:17发布

I'd like to customize some of the MATLAB uicontrols (such as the drop-down box) to give them more user-friendly functionality.

My question is: Is it possible to extend/inherit the uicontrol? If so, how do you do it? If not, is there a workaround?

I have tried this basic code just to get it setup, but I receive the following error:

The specified super-class 'uicontrol' contains a parse error or cannot be found on MATLAB's search path, possibly shadowed by another file with the same name.

classdef ComboBox < uicontrol    
    methods(Access = public)
        function obj = ComboBox()
            set(obj, 'Style', 'popup');
        end 
    end
end

The error occurs when I try to add it to a figure:

cmb = ComboBox();
set(cmb, 'Parent', obj.ui_figure);

Edit: After thinking about it, I think this would be a decent workaround, however, I'd still like to know how to extend uicontrol if it's possible.

classdef ComboBox < uicontrol    
    properties(Access = public)
       Control;
    end

    methods(Access = public)
        function obj = ComboBox(parent, items)
            obj.Control = uicontrol();
            set(obj.Control, 'Style', 'popup');
            set(obj.Control, 'Parent', parent);
            set(obj.Control, 'String', items);
        end 
    end
end

1条回答
疯言疯语
2楼-- · 2019-07-15 17:35
  1. There is no documented way (as of R2013a) to write subclasses to MATLAB Handle Graphics classes. In fact, because of the way MATLAB stores the hg objects, we can't even get the class of an hg object easily. For example:

    >> fig = figure();
    >> class(f)
    
    ans =
    
    double
    
    >> isa(f, 'figure')
    
    ans =
    
         0
    
    >> ishghandle(f)
    
    ans =
    
         1
    
  2. One solution to this is to write a class which subclasses either handle, or
    hgsetget, and keeps a handle to a uicontrol object as a private property. For example:

    classdef ComboBox < hgsetget
        properties (Access = private)
            Control
        end
    
        properties
            % extend the functionality of your new uicontrol with additional
            % properties
            newProp1
            newProp2
        end
    
        properties (Dependent = true)
            % make any properties of uicontrol for which you want to still
            % allow access as dependent properties. define set and get methods
            % for these properties below
            fontSize
            foregroundColor
            backgroundColor
            items
        end
    
        methods
            function obj = ComboBox(parent, items)
                obj.Control = uicontrol(parent, 'Style', 'popup', ...
                    'String', items);
                % make sure to delete this object if you delete the uicontrol
                set(obj.Control, 'DeleteFcn', {@(source, eventData)delete(obj)})
            end
    
            % Define set and get methods for your new properties. These methods
            % will set the actual properties, and then modify the uicontrol in
            % some way
            function prop = get.newProp1(obj)
                prop = obj.newProp1;
            end
    
            function set.newProp1(obj, newVal)
                obj.newProp1 = newVal;
                % do something else
            end
    
            function prop = get.newProp2(obj)
                prop = obj.newProp2;
            end
    
            function set.newProp2(obj, newVal)
                obj.newProp2 = newVal;
                % do something else
            end
    
            % Define set and get methods for any uicontrol properties you wish
            % to retain. These methods will simply redirect calls to the
            % uicontrol object.
            function size = get.fontSize(obj)
                size = get(obj.Control, 'FontSize');
            end
    
            function set.fontSize(obj, newSize)
                set(obj.Control, 'FontSize', newSize);
            end
    
            function color = get.backgroundColor(obj)
                color = get(obj.Control, 'BackgroundColor');
            end
    
            function set.backgroundColor(obj, newColor)
                set(obj.Control, 'BackgroundColor', newColor);
            end
    
            function color = get.foregroundColor(obj)
                color = get(obj.Control, 'ForegroundColor');
            end
    
            function set.foregroundColor(obj, newColor)
                set(obj.Control, 'ForegroundColor', newColor);
            end
    
            % You can even rename some uicontrol properties to fit your
            % purpose.
            function items = get.items(obj)
                items = get(obj.Control, 'String');
            end
    
            function set.items(obj, newItems)
                set(obj.Control, 'String', newItems);
            end
    
        end
    end
    

    You can then use the ComboBox as you would any other uicontrol handle:

    obj = ComboBox(figure, 'hello|goodbye');
    set(obj, 'items', 'newItem1|newItem2');
    
  3. There are undocumented ways of extending handle graphics classes, but I'm not familiar with them. Check out this reference: http://undocumentedmatlab.com/blog/introduction-to-udd/

查看更多
登录 后发表回答