Distinguish uifigure from figure programmatically

조회 수: 29 (최근 30일)
Adam
Adam 2017년 7월 12일
댓글: Matt J 2024년 1월 28일
Is it possible to distinguish a uifigure (appdesigner) from an old-style figure programmatically by an if type test?
class( hFig )
returns
'matlab.ui.Figure'
for both of them and I can't see anything obvious in the metaclass or properties that I can use to check which it is.
I could just use a try-catch, but I'd prefer to just filter uifigures than catch the error (I have a BusyCursor class which changes the pointer on all open figures to the busy cursor and then back again when it is deleted, but it crashes on uifigures which do not support changes to the 'pointer' property).
  댓글 수: 2
David Young
David Young 2021년 5월 21일
The solutions so far are all complex and sometimes undocumented. It seems strange that even in R2021a there isn't a simple isuifigure (or equivalent) function as part of the system. I can't believe users are expected to delve into the error generation mechanism of uialert to find out what to do. Using try-catch seems the simplest and most reliable way - and that's just horrible.
Adam Danz
Adam Danz 2021년 5월 21일
It depends on what you're doing with the figure. Try/catch won't do squat if you need to work with the figure position property, for example, since the two types of figures have different position definitions and getting/setting position won't cause an error.

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

채택된 답변

Ralph Coleman
Ralph Coleman 2019년 9월 18일
편집: Ralph Coleman 2019년 9월 18일
Hi
From R2018b, you can simply use:
matlab.ui.internal.isUIFigure(hFig)
  댓글 수: 5
Markus Leuthold
Markus Leuthold 2022년 6월 14일
looking at the code of isUIFigure, it boils down to checking the property JavaFrame_I
% if JavaFrame is empty, then this is a web figure.
if ~isempty(f) && isempty(get(f,'JavaFrame_I'))
bool = true;
else
bool = false;
end
Matt J
Matt J 2024년 1월 28일
however regular figures generated in live editor are incorrectly identified as UIFigures using Ralf's method
I wonder if that's really incorrect. You could argue that a Live Scipt is an app window environment, so figures embedded there should be seen as uifigures.

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

추가 답변 (4개)

Zhengyi
Zhengyi 2019년 2월 18일
편집: Zhengyi 2019년 2월 18일
TL;DR
function val = isuifigure(h)
val = ~isempty(matlab.ui.internal.dialog.DialogHelper.getFigureID(h));
end
The slightly longer story
If you type the following into the console, you will get an error:
>> uialert(figure,'a','b')
Error using uialert (line 42)
First argument must be a figure handle created using the uifigure function.
On line 42 of uialert function, we can see it uses the following method to validate the input handle:
matlab.ui.internal.dialog.DialogHelper.validateUIfigure(hUIFigure)
By reading through this function, we can see the error is thrown when the following function returns empty:
matlab.ui.internal.dialog.DialogHelper.getFigureID(h)
and
function out = getFigureID(f)
out = f.getId();
end
However,
getId()
seems to be a private function. The only option we have is to use getFigureID and check whether it returns a non-empty value.
Finaly, if you like, you can create this utility function to help you get over the long function call:
function val = isuifigure(h)
val = ~isempty(matlab.ui.internal.dialog.DialogHelper.getFigureID(h));
end
  댓글 수: 1
Adam Danz
Adam Danz 2021년 3월 4일
편집: Adam Danz 2021년 3월 7일
Thanks for digging, @Zhengyi. This solution works all the way back to r2016a which is when uifigures were released. However, is breaks in r2020b (and, perhaps, prior releases) when the handle was created by figure().
matlab.ui.internal.dialog.DialogHelper.getFigureID(figure)
% Error:
% First argument must be a figure handle created using the uifigure function.
A workaround would be to use a try/catch and to test the MException for the error ID 'MATLAB:uitools:uidialogs:NotAnAppWindowHandle' but, according to your answer, that line returns an empty value in earlier releases and who knows if this error message will change in the future.

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


Dev-iL
Dev-iL 2017년 8월 15일
I tried comparing the outputs of:
F = struct(uifigure());
G = struct(figure());
There are several fields that are different by default. Of increased interest are:
JavaFrame, Controller, ControllerInfo, NodeChildren
I cannot guarantee that it will work 100% of the time, but you can try testing for
isstruct(struct(hFig).ControllerInfo)
... if the above returns "true" - it's likely a uifigure.

Andreas Klotzek
Andreas Klotzek 2019년 1월 9일
Hi
I also need an answer to this question.
The answers provided here are not certain to give the correct result. For example if I have a old-style figure with property HandleVisibility = 'off', the test using groot will give the wrong result.
Using properties is also not a stable idea. The behavior might change.
The problem is not only for figure and uifigure. I need the same check on axes/uiaxes or uipanel handles, basically on any graphics handle. One could probably use the ancestor function to redirect the problem for any graphics handle to the figure handle.

Celso Reyes
Celso Reyes 2018년 8월 20일
편집: Celso Reyes 2018년 8월 21일
The new figures do not show in groot by default -- At least as of Mac version, R2018a -- when ShowHiddenHandles is 'off'. If ShowHiddenHandles is 'on', then it will appear.
As a side note, the new-style uifigure appears when you use allchild(groot) regardless of the ShowHiddenHandles value.
So, one could non-invasive check would look like so...
function style = figtype(f)
g = groot;
oldStatus = g.ShowHiddenHandles;
g.ShowHiddenHandles = 'off';
if any(g.Children == f)
style = 'figure';
else
style = 'uifigure';
end
g.ShowHiddenHandles = oldStatus;
end
So, in practice...
>> newf = uifigure('Name','new');
>> oldf = figure('Name','old');
>> figtype(newf)
ans =
'uifigure'
>> figtype(oldf)
ans =
'figure'
I'm not sure what would make a regular figure's handle hidden, since the Visibility property doesn't do it.

카테고리

Help CenterFile Exchange에서 Develop uifigure-Based Apps에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by