Check if a graphics object is visible to the user

7 ビュー (過去 30 日間)
Justin Solomon
Justin Solomon 2015 年 6 月 18 日
編集済み: Alfonso Nieto-Castanon 2015 年 6 月 20 日
The short version: Is there an easy way to check if a given graphics object is visible on screen? (Note that its visible property will not necessarily tell me this since its parent could be invisible while the object itself is visible).
The long version: Imagine you have a GUI with tabs (each tab containing an axes) and you want to add a callback that is invoked when the user moves the mouse scroll wheel. The callback needs to act differently depending upon which axes the mouse is currently positioned over. However, if the axes are positioned in the same location on screen in the different tabs, then the mouse is actually positioned over all of them. Thus I need to know which object is actually visible to the user and have the callback act accordingly. Also, because I'm trying to make this callback as generalizable as possible, the callback itself is ambivalent to the whole structure of the GUI so I can't just check which tab is currently selected. (I'm doing it this way so that I can reuse this code for other projects where the GUI design may be different from this specific case).
Any ideas would be appreciated. I could probably go handle diving and recursively figure out if an object is visible on screen, but I'd rather not have to do that if there's a simpler (and faster) way. Thanks!
Justin

採用された回答

Alfonso Nieto-Castanon
Alfonso Nieto-Castanon 2015 年 6 月 18 日
While it is simple to check which object is visible, e.g.:
function ok = isvisible(handle)
ok = true;
while ok&&~isequal(handle,0),
ok = strcmp(get(handle,'visible'),'on');
handle = get(handle,'parent');
end
things become much more complicated when you have several objects that may be all visible over the same position of the screen and you need to figure out which one is displayed "on top". This depends on the specific Matlab version and nature of the objects, so it is rather complicated as far as I know to make it work generally.
An alternative approach would be to have your GUI explicitly indicate which objects should be considered "active" at any time, for example by setting the 'tag' or 'userdata' properties on the objects themselves, or by invoking some function which keeps/updates a list of currently active objects. The latter approach is typically more general, since specific GUIs might want to reuse these same object property to other ends, and perhaps more flexible as well (e.g. you may want to define an invisible axes that still captures the user actions over an arbitrary area). Depending on how fancy you want your code to get, you may want to define a class wrapping your graphic object handles which keeps track of this sort of things for you.
  2 件のコメント
Justin Solomon
Justin Solomon 2015 年 6 月 19 日
Thanks for your response and example. Yes it seems really tricky to figure out which object is actually visible to the user. Also, the code above doesn't work in cases where you have objects in tabs (uitab doesn't have a visible property unfortunately). Could probably handle that situation with the try catch blocks thought.
Alfonso Nieto-Castanon
Alfonso Nieto-Castanon 2015 年 6 月 20 日
編集済み: Alfonso Nieto-Castanon 2015 年 6 月 20 日
You are right, sorry about that. You should be able to fix that (and make the code compatible across most Matlab versions, including the new or old graphic system) using something like:
function ok = isvisible(handle)
ok = true;
while ok&&handle~=0,
try, ok = strcmp(get(handle,'visible'),'on'); end
handle = get(handle,'parent');
end
(this assumes that objects without a 'visible' property are always visible, which seems like a fair assumption, and it will use the implicit casting of graphic handle objects as doubles to identify the 'root' object in Matlab versions that use the new graphic system)

サインインしてコメントする。

その他の回答 (1 件)

Walter Roberson
Walter Roberson 2015 年 6 月 18 日
This is difficult because it depends on the active Renderer and upon the release. There is an interesting article at http://blogs.mathworks.com/graphics/2014/11/04/sortmethod/
  1 件のコメント
Joseph Cheng
Joseph Cheng 2015 年 6 月 18 日
編集済み: Joseph Cheng 2015 年 6 月 18 日
or... just a quick while loop looking for if the parent is visible or not..
h = figure;
for ind = 2:6
h(ind) = uipanel('parent',h(ind-1),'Title',['Main Panel' num2str(ind-1)],'FontSize',12,...
'BackgroundColor','white',...
'Position',[.01+ind/40 .01+ind/20 .9-ind/20 .9-ind/20]);
end
%set one to visible off
set(h(4),'visible','off')
%check to see if panel 5 is visible
isvisible = strcmp(get(h(6),'visible'),'on');
prnt = get(h(6),'parent');
while prnt~=0
isvisible = strcmp(get(prnt,'visible'),'on');
if isvisible ==0
break
end
prnt = get(prnt,'parent');
end
switch isvisible
case 1
disp('is visible');
case 0
invisparent = get(prnt,'title');
disp(['not visible because ' invisparent])
end

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeGraphics Object Programming についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by