uitab Position doesn't update unless drawnow is called while the parent figure is visible

4 visualizaciones (últimos 30 días)
I have a figure created with figure(). Within it I have a uitabgroup() that has a uitab() and a uitable() put in the tab. I'm trying to set the position of the table to fit properly within the uitab. What I have discovered is that if I set the size of the uitabgroup, uitab is supposed to inherit properties (uitab.Position is read only) so then I can size uitable to fit within uitab.Position and have clean edges on my objects. I'd like to be able to do this with the overall figure visibility OFF so people don't see the jumping around of components while I move and shape stuff.
Here's the basics of what I made:
d = figure('Visible','off');
method_tab_holder = uitabgroup('Parent',d);
method_tab = uitab('Parent',method_tab_holder);
method_table = uitable('Parent',method_tab);
The problem is that the uitab doesn't inherit any Position properties until a drawnow is called while the uitab is visible.
Here's a bit of stuff I did to follow the process. I check the values after creation but before positioning, after positioning but before drawnow calling, and after calling drawnow:
before_position_changes = [method_tab_holder.InnerPosition ; method_tab.InnerPosition ; method_table.Position]
after_position_changes = [method_tab_holder.InnerPosition ; method_tab.InnerPosition ; method_table.Position]
afterDrawNow_position_changes = [method_tab_holder.InnerPosition ; method_tab.InnerPosition ; method_table.Position]
This returns the following:
before_position_changes =
1 1 300 400
1 1 300 400
20 20 300 300
after_position_changes =
5 5 200 300
1 1 300 400
5 5 190 290
afterDrawNow_position_changes =
5 5 200 300
1 1 300 400
5 5 190 290
But if I run them with Visible turned on
d.Visible = 'on';
drawnow
I get this where method_tab has properly inherited size after the drawnow
before_position_changes =
1 1 300 400
1 1 300 400
20 20 300 300
after_position_changes =
5 5 200 300
1 1 300 400
5 5 190 290
afterDrawNow_position_changes =
5 5 200 300
3 4 195 270
5 5 190 290
As I said above, I can work around this BUT it is tiresome because I like to keep figures hidden until their layout is set so people don't see stuff jump around on their screen. Also, making the uitabgroup visible while the parent figure is invisible does't solve it - it appears it has to be rendered on screen before the Position properties inherit properly. Anyone know a workaround so I don't need to make stuff visible while setting positions?
  1 comentario
Smattering_Applause
Smattering_Applause el 2 de Feb. de 2021
Is it related to this line of text from the uitabgroup help doc? The internal SizeChangedFcn that always runs doesnt occur until visible.
Changing the size of an invisible container triggers the SizeChangedFcn callback when it becomes visible.

Iniciar sesión para comentar.

Respuesta aceptada

Jan
Jan el 2 de Feb. de 2021
Editada: Jan el 2 de Feb. de 2021
Did you try to create the figure with enabled visibility but outside the visible scrren?
d = figure('Visible','off');
origPos = d.Position;
d.Position = origPos - [0, 2000, 0, 0];
d.Visible = 'on';
... Your code here until the figure is created.
d.Position = origPos;
  1 comentario
Smattering_Applause
Smattering_Applause el 2 de Feb. de 2021
Good call on the workaround, shoving it somewhere offscreen but with .Visible = 'on'; allows the update to occur but without showing self adjusting.

Iniciar sesión para comentar.

Más respuestas (1)

Walter Roberson
Walter Roberson el 2 de Feb. de 2021
The analysis is correct. Information about container size is not updated until the object is rendered.
Approximately speaking, for efficiency you cannot recalculate all downstream properties each time you make a change, as you might not even have consistent properties, especially if you are using assignment syntax to update properties as semantically that only permits updating one property at a time (whereas set() could potentially represent a batch.)
Thus you need a semantics to say "Begin a batch. Record this list of updates to be made, but do not put it all in effect yet as you do not have a consistent view yet. Ok, end the batch and make all those changes at once (or in a hierarchical order)".
MATLAB did not choose to define an explicit "begin" operation. Instead it just defined the "end" operation, and that defined "end" operation is rendering to the screen. Automatically calculated positions and sizes of objects are not calculated until rendering, under the hypothesis that you might be in the middle of making a batch of changes.
You are correct that this does mean that in cases where you need to know how big something is that was automatically sized (or size changed due to user actions), that you have to render it, and that risks it becoming visible to the viewer in the time before you can make it invisible again.
This used to be a continual challenge when you needed to know the screen real-estate needed for some block of text in a proportionately spaced font especially if the user had control of font size or family. You might need that information to figure out the optimal placement of objects, creating boxes just large enough to hold a heading, (e.g. not wasting space now against the possibility that some day in the future someone might want a 30 point font for some reason.) A small number of releases ago a feature was added for this specific purpose of asking about required text size; I have not used it yet to have memorized the function name for that.
You are right, it is a problem, and it is a general problem... but there are also reasons why updates are not done immediately.
MATLAB could add some kind of "release" operator that triggered the updates without having to make them visible, but it has not done so.
  1 comentario
Smattering_Applause
Smattering_Applause el 2 de Feb. de 2021
MATLAB could add some kind of "release" operator that triggered the updates without having to make them visible, but it has not done so.
That would be ideal - I can understand why they wouldn't want to do the inherit without a cause, but I would have thought calling drawnow would force it to occur, even if nothing is functionally drawn (even offscreen).

Iniciar sesión para comentar.

Categorías

Más información sobre Graphics Performance en Help Center y File Exchange.

Productos


Versión

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by