Detect if variable is a GUI container
Ältere Kommentare anzeigen
Hi!
For my code I'm using quite a lot of classes and functions, and some of them require or produce a GUI object. Sometimes i also want that they work inside a supplied GUI container (it can be a figure, a tab, a panel or whatever).
Now, supposing to always have proper inputs is not so good, so I want to check them using something like validateattributes.
I can insert all the possibilities, but it would be better (and more flexible) to use some sort of built in check, maybe thre one used for the "parent" properties of other objects, but I cannot find this function.
Is there anybody that know it?
Thanks,
Jacopo
5 Kommentare
Jacopo Remondina
am 30 Nov. 2018
Adam
am 3 Dez. 2018
I tend to validate most of my function inputs and often write classes that involve plotting something (either on a supplied axes or creating one if the supplied axes is empty) or adding a UI component to a parent, but I tend to take each case as it comes. e.g.
validateattributes( hParent, { 'matlab.ui.container.internal.UIContainer', 'matlab.ui.Figure' }, { 'scalar' } )
is what I am currently using to test the handle of a parent object that I am going to attach e.g. a uiccontrol or a uipanel to.
try
validateattributes( hAxes, { 'matlab.graphics.axis.Axes' }, { 'scalar' } )
if ~ishghandle( hAxes )
error( 'hAxes must be a valid axes handle' )
end
catch e
throwAsCaller(e);
end
is what I use for validating an axes handle that I want to plot something on, etc etc. So I'm not convinced a 'one size fits all' validation of anything and everything makes too much sense.
Jacopo Remondina
am 3 Dez. 2018
I do not see, that this is simpler than
if ~isgraphics(Variable, 'axes')
error('hAxes must be a valid axes handle')
end
Akzeptierte Antwort
Weitere Antworten (1)
Perhaps you mean:
ishghandle(Variable)
or
isgraphics(Variable, 'panel') % To detect a panel object
% [EDITED] This means:
isgraphics(Variable, 'uipanel') % To detect a uipanel object
13 Kommentare
Jacopo Remondina
am 30 Nov. 2018
@Jacopo: As I have posted already, you need the command isgraphics or use ishghandle and compare the property type also.
Pleae notice, that it is hard to answer to terms like "and similar stuff" or "new containers that will be added in future version". It is impossible to write code with a forward compatibility based on future decisions of MathWorks.
To detect a uipanel object, use:
isgraphics(Variable, 'uipanel')
The string 'panel' was a typo only. Please read the instructions for:
doc isgraphics
Maybe:
if ishghandle(H) && any(strcmpi(H.Type, {'figure', 'uipanel', 'uitab'}))
Jacopo Remondina
am 30 Nov. 2018
Jan
am 30 Nov. 2018
I would hesitate to write a function, which tries to "insert something to H" without any hard limitations of what "H" is. Imagine that H is a class, which stores Graphic Handles. Then "inserting" works fine, but does something completely different than inserting an axes into a figure. A simple try catch will not be safer than checking the Type property of a Handle, which was checked to be a Graphic Handle before.
Jacopo Remondina
am 30 Nov. 2018
Jan
am 30 Nov. 2018
You wrote "a lot of classes and functions", so H can be a variety of things. If it is a function handle of a function, which do not need an input, calling it can cause troubles. For a function, which needs an input, the error message is not easy to understand. Creating UI objects can have side-effects like setting the current figure as active object. If now any other code relies on another figure to be active, e.g. a plot without specifying the 'Parent' object, this test can cause more troubles than it solves.
Jacopo Remondina
am 30 Nov. 2018
Jan
am 3 Dez. 2018
@Jacopo: What exactly does "activeH=gca/gcf" mean as code? Remember that calling gcf creates a new figure, if there is no one open, and gca creates a new axes and a new figure, if no figure is open. An exhaustive and safe test is not trivial. If you have written one and are willing to publish it, it would be welcome and useful in the FileExchange.
If a dynamic check of the objects is really needed, it is smarter to implement this in the data structure actively, not in the passive error handling. E.g. you can create the objects directly with a field, which defines, if it is of the wanted type. E.g.:
obj.handle = figure;
obj.isContainer = true;
This is straight and clear and does not contain any dependencies to potentially new classes in the future, which can have unpredictable side-effects on calling.
Jacopo Remondina
am 3 Dez. 2018
@Jacopo: isgraphics(Variable, 'uipanel') does not use tags, but the type of the object. You have accepted an answer now, which uses ishghandle , which does exactly the same as isgraphics except that you cannot specify the type of the handle, which way a part of your question. I've suggested ishghandle also some days ago. Testing:
validateattributes( hAxes, { 'matlab.graphics.axis.Axes' })
is exactly the same as:
isgraphics(Variable, 'axes')
but the latter does not depend on the internal representation of the axes object, such that it is more compatible with different Matlab versions.
I assume you mean: "check if a normal handle is an figure or not". I still think, that this is done directly by:
isgraphics(Variable, 'figure')
Jacopo Remondina
am 3 Dez. 2018
Jan
am 3 Dez. 2018
Dear Jacopo: No problem, I do never feel upset in the forum. I'm happy if your problem is solved. It was the demand for "new containers that will be added in future version" which let me think, that the compatibility between Matlab versions is important.
Thhis code checks for UIContainers and figures:
validateattributes(h, ...
{'matlab.ui.container.internal.UIContainer', 'matlab.ui.Figure'}, ...
{'scalar'})
You asked for "a figure, a tab, a panel or whatever" and "(ui)figure, uitab, uipanel, gridLayouts". Of course you have to add the further elements here also, so 'matlab.ui.container.internal.UIContainer' does not catch all objects you have asked for - as isgraphics does not also. I'd still prefer:
isgraphics(h, 'uicontainer')
because it does not depend on the (as fas as I know not documented) type 'matlab.ui.container.internal.UIContainer'.
Nevertheless, if it is the solution of your question, everything is fine. Then I simply do not understand the question, but this is not a problem which needs a solution ;-)
Adam
am 4 Dez. 2018
Yeah, I originally posted mine as a comment (as I tend to nowadays with 80-90% of my contributions since I don't like things being posted as answers that do not fully answer the question, but if the questioner requests it then I do) because it was never meant as a final solution to the problem, more just a suggestion of 2 examples of what I do, copy-pasted from the functions I use. In my case I maybe want fewer things to act as parents - e.g. I never add uicontrols directly to a tab. when I am doing a programmatic UI I am always using the GUI Layout toolbox so I always have things either in a layout (uix.HBox or uix.VBox) which is where the selection of things in my validation comes from. I do sometimes add panels directly to a figure though which is why I guess I have that included.
My axes validation is quite old so there are other useful functions too for that, though I generally use validateattributes because I don't want the boolean return type, I just want an error thrown. Obviously in this case, since I wrapped it up in its own validateAxes function (I didn't include that bit) I could just as easily have captured the boolean and thrown the error all in one go anyway!
Kategorien
Mehr zu Creating, Deleting, and Querying Graphics Objects finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!