Detect if variable is a GUI container
이전 댓글 표시
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
Jacopo Remondina
2018년 11월 30일
Adam
2018년 12월 3일
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
2018년 12월 3일
I do not see, that this is simpler than
if ~isgraphics(Variable, 'axes')
error('hAxes must be a valid axes handle')
end
채택된 답변
추가 답변 (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
Jacopo Remondina
2018년 11월 30일
@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
2018년 11월 30일
Jan
2018년 11월 30일
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
2018년 11월 30일
Jan
2018년 11월 30일
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
2018년 11월 30일
Jan
2018년 12월 3일
@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
2018년 12월 3일
@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
2018년 12월 3일
Jan
2018년 12월 3일
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
2018년 12월 4일
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!
카테고리
도움말 센터 및 File Exchange에서 Creating, Deleting, and Querying Graphics Objects에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!