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

Jan
Jan 2018년 11월 30일
편집: Jan 2018년 11월 30일
What is your question? What does "work inside a supplied GUI container" mean? What should do which work? What exactly is a "whatever"?
Jacopo Remondina
Jacopo Remondina 2018년 11월 30일
What is your question=i edited it, now it should be clear;
work inside a supplied GUI container: i.e. plot() can create an axes, use the actual one (gca) or a supplied one. I want something similar;
What should do which work: my function/method in which I set as input also "Parent",MyPanel for example;
Whatever: (ui)figure, uitab, uipanel, gridLayouts, etc (including, if possible, new containers that will be added in future version)
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.
Thanks @Adam!
This was what I was looking for: simple, efficent and working as expected. If you want to create a proper answer (just copy/paste your comment), I will upvote it
Jan
Jan 2018년 12월 3일
편집: Jan 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

댓글을 달려면 로그인하십시오.

 채택된 답변

Adam
Adam 2018년 12월 3일
편집: Adam 2018년 12월 3일

1 개 추천

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.
It's also useful to note that if you ever want to know the class type to test for you can just create one of the elements in question and class class on it.
e.g.
figure; hAxes = gca;
class( hAxes );
and then just paste the answer into the validateattributes call.

추가 답변 (1개)

Jan
Jan 2018년 11월 30일
편집: Jan 2018년 11월 30일

0 개 추천

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

ishghandle(Variable)
return true for both a figure, a (ui)panel, an axes and a line plot, but you cannot insert an axes (or any other graphical object) in the later two.
isgraphics(Variable, 'panel')
return false for all of the above.
Instead I want something that return true for figures, panels, tabs, layouts and similar stuff and false otherwise
(someway similar to isnumeric(x): it return true if x is one of the numeric variable type, and not just if its a double)
Jan
Jan 2018년 11월 30일
편집: Jan 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'}))
@Jan:
<<Pleae notice, that it is hard to answer to terms like "and similar stuff" or "new containers that will be added in future version">>
I know this. And I know that is also hard to code with forward compatibility. But I don't think that at mathworks they will change many class every time they add a new layout manager or something like that (that's why isnumeric exist; and if you ever use java, you should know that any graphical container is an extension of the same abstract class).
if ishghandle(H) && any(strcmpi(H.Type, {'figure', 'uipanel', 'uitab'}))
this can work in some way, but not so good. A more general way could be to try to insert something in H, cathing the eventual error and deleting the inserted object. In this way you could be sure that H is a container. If nobody can suggest me a quicker (and maybe better) way, I will implement this general function
Jan
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.
try
a=uibutton(H,"push","Tag","container test")
delete(a)
catch ME
%ME.identifier check
end
How this cannot be "safe"? If H is a class, also a custom one, that can accept a uibutton as a Children, then this is something that should return true for my purpose. Otherwise uibutton should trow an error that I can catch
Jan
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
Jacopo Remondina 2018년 11월 30일
True. But at least the second problem can be avoid by getting the activeaxes/window ( activeH=gca/gcf), performing the test and then calling figure(activeH) or axes (activeH).
The first instead can be limited by some ME.identifier check, as I already suggested in the previous comment
@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.
"activeH=gca/gcf" save in the variable activeH the current axes or the current figure (depends on which shortcut you use);
And no, i haven't written (yet) any proper code, otherwise I would not have opened this thread but used my own code. Maybe I will write, test and publish it someday.
And again, your proposed code is not what I'm looking for: I don't want to use any tags (or otherwise I would have save it in the "Tag" or "userData" fields of the graphical handle), but to check if a normal figure is an handle or not.
Jan
Jan 2018년 12월 3일
편집: Jan 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')
Dear @Jan,
I understood that you put a lot of effort in replying me, and now you feel a bit upset because I upvoted another user that just arrived later and, saccording to you, didn't wrote nothing new.
But he actually did.
Again, also in your last comment, you proposed me something VERY specifical:
isgraphics(Variable, 'uipanel')
You are checking for JUST uipanels. That's easy. isa(H, "uipanel") or many other way (isgraphics, hghandle,etc...). BUT as I stated from the beginning, I did NOT want something specific, but something generic.
I upvoted Adam answer not for the try/catch statement, actually I didn't have to look at it, because the answer to my question arrived early: I was looking for just the class name of uicontainers: "matlab.ui.container.internal.UIContainer". I can write my own code around it, both using isa, validateattributes, a try/catch statement or whatever. But I need to know what I have to look for. if you, in your first comment, just wrote that class name with or without other two pages of the reason why I should have check it in a way or in another, I would have voted your answer. But you prefered to stick on performing multiple test on the single component. That's why I coudn't vote your answer.
Hope next time we can solve our problems on how to get a good code in a faster way.
Thanks again for your efford (also if it didn't solved my problem.
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
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에 대해 자세히 알아보기

질문:

2018년 11월 30일

댓글:

2018년 12월 4일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by