Opposite of drawnow - prevent changes to a listbox

I am using GUIDE to create plots of experimental data. In my figure, I have menus in which I store the input data categories and output categories of functions that I run on that data.
As I operate on those plots, the need arises to change the contents of those menus, operate on the data, then change the menus back to a presentable format.
In essence, I am trying to prevent those menus from being visibly updated, while still changing the contents so I can use them to do what I need to do. Since drawnow forces a graphical update, I was wondering if there was an opposite equivalent of that call.
Any comments and suggestions are welcome.

 Risposta accettata

About the only equivalent is to set the visibility of the items to be off. The items disappear from view, but any internal changes do not result in visible changes until the visibility is set back on again.

5 Commenti

I considered that, but my optimal solution results in no change at all to the items in question.
As it sits now, the change happens fast enough to be, in most cases, not noticeable. However, when I am operating under heavier loads and MATLAB slows down, I can detect a change.
The main focus of this question was to eliminate any sort of graphical update to the GUI elements. I apologize if that was not clear at first.
The guarantees that Mathworks makes are that graphics are not updated unless you use one of figure(), pause(), drawnow(), uiwait()/waitfor(), or MATLAB has nothing left to do (all callbacks have been returned from), or MATLAB is at the keyboard() prompt (including debugging). Or, I guess, if a figure is made visible.
Until you reach one of those, MATLAB does not even process layout. Sometimes you find that you need MATLAB to process layout so you can query the layout, even though you do not actually want the change to become visible. For example if you want to know how tall a string would render at so that you can dynamically resize a control, you need to trigger layout so you can query its extent property even though you might not want the control to appear at that time.
While investigating my need to trigger layout, grab the results, and zap the temporary graphics object, all without the temporary graphics object becoming visible, I found that in practice MATLAB has an ill-defined graphics command latency for visibility of changes. If you make a graphics change and trigger it to become visible, and then you change it right back again "quickly enough", then the user never sees the quick change, not even a flicker. I found that undoing the graphics change on the next one line or next two lines was usually "quickly enough"; by three lines later it was not always "quickly enough" (but usually was.)
Now if you need to make a graphics change and for some reason your code contains one of the graphics update triggers, and then you want to call a routine to do some work for you with the changed versions, and eventually change it back... then that sequence is almost certainly too long and you will probably get a visible graphics update.
You can reduce these effects by removing drawnow(). Only put them in at places that you are sure you need to force the screen to repaint. If the graphics update can wait until the callback is finished, leave out the drawnow() -- because then you have the possibility to make graphics object changes, execute, and change back, without the user seeing any visible change.
My most troublesome updates come when I am updating the contents of my menus.
I don't know if the version is relevant, but I am stuck with 2010b.
Whenever I do menu updates, I have to do a "set" call:
set(handles.exampleMenu,'String',contentCell);
Those set() calls are forcing the graphical update that I was having problems with (see my comment on your other comment below - I have changed the program, but this answer piqued my interest).
So in essence, I rarely have any drawnow() calls because these set() calls and plot() calls already force updates. I guess those would be the most useful to suppress, but I'm not sure if it's possible.
Even in R2010b, using set() should never trigger immediate graphics updates except perhaps setting figures visible -- with the exception that if you are at the command line (especially the debugger) then the graphics is updated before the prompt is given.
Ah. Did not know that.
Also accepted your answer due to the help and advice you have given with regards to this question.

Accedi per commentare.

Più risposte (1)

Bill York
Bill York il 10 Feb 2017
It sounds like you want to update the graphics without updating the menus. There is no way in MATLAB to do this.
Could you tell me more about how you are using the menus? There may be another way to achieve your goal that does not collide with updating the graphics.

8 Commenti

I think they want to update the menu without having it make a visible difference, such as if their code fetches values from the graphics objects.
I am using the menus to hold a set of functions that correspond to outputs calculated from the input experimental data. The user can navigate these menus to select which outputs to display on the plot in the GUI. What I wanted to do was be able to use a sort of transformation on that menu so I could dynamically access my output structure by re selecting what the user had selected. Then, I would transform the menu back to its original state to preserve the outward appearance of the GUI.
Is this fine, or should I consider something different?
I have used similar approaches at times, Matthew.
However, my experience over time has been that this approach is triggered by holding control and data parameters in the wrong place. It is needed when the "primary" information is being held in graphics objects, when what is better is to use the graphics callbacks to access information held elsewhere. If the graphics objects are not considered to be authoritative about what the information "really" is, then you can control the program by changing what is "really" there without changing the graphics.
I also find that when these schemes become attractive, that I have usually hard-coded access to the primary data when really I should be creating a parameter set and telling the code to work on the parameter set. Instead of the code continually accessing an equivalent-to-global "master" copy of the data, the flow of control should be able to conjure up what could be called a "hypothesis variant" and the routines would work on that. (I say "equivalent-to-global" because although guidata() against your main figure might not technically use the keyword "global", in practice it is used very much the same way.) Unfortunately the way that callback routines are invoked in the base workspace makes a bit tricky to designate which hypothesis variant you are processing at any one time.... it isn't like in more linear programming where you can just create a control structure and each level of call passes it down as needed.
Anyhow... if you are manipulating graphics object properties because routines expect to read the properties out of the graphics objects in order to determine flow of control or flow of data, then you have put the information in the wrong place.
In smaller programs, I end up holding information in graphics objects a lot. It is easy to do. It works okay for less complex programs. It just doesn't turn out to be sustainable for larger programs.
That makes sense to me. After reading these replies, I have ended up refactoring how that part of my program works. Now instead of data field names being accessed from the altered menu, they are simply stored in a structure in the handles structure.
I never really consciously thought of the guidata() call as one to a global variable, but that makes sense now.
Thank you for the help!
guidata() is not quite global data, but we tend to treat it like it is and we tend to get annoyed when it does not act like global data.
guidata() is attached to the figure that is the ancestor of the object passed as the first parameter to guidata(). That allows there to be multiple such structures that you can distinguish. But if you do have more than one figure then chances are that you want to be able to access data between them and then the separation gets annoying...
If you are using multiple figures then you might well also be finding objects by tag, and then you have the problem that tag names are not qualified by figure. You have to know to pass an appropriate parent object in to findobj().
It is not clear to me what a better way would be to keep data separate but allow convenient sharing across data pools.
Yeah, in total I have 11 figures (most are relatively simple, about 3 are fairly complex). they are all controlled through one main figure, so I pass data to them using the handles/guidata structure.
So in my case, the data is fine being conglomerated into one large mass. I do all of my division through aptly named structures.
Using GUIDE helps tremendously with that, as I can preallocate axes and menus tags in order for population later.
GUIDE uses guidata() relative to the object whose callback is being invoked, which refers back to the figure enclosing that object. That has some advantages, but if you are working in the mode of having a "main" GUI figure and other figures that are under the control of the main figure, then it is more common than not to want the controls in the secondary figures to be able to refer to data in the main figure.
I do not know if there are good solutions to the complex interactions. Perhaps if you could somehow designate a particular data pool to be used by the figure and if the data pool could be shared between multiple figures.
I just use the handles structure for that.
GUIDE automatically generates it to store all tags for the figure objects when it initializes the GUI and maintains it as long as the figure's open. For my main figure, I initialize data storage fields in the opening function. For "sub"-figures, I pass through the main figure's handles structure as an argument to its opening function and access the data that way.
That way I can call guidata() on my handles structure as it is tied directly to each figure.

Accedi per commentare.

Categorie

Scopri di più su Creating, Deleting, and Querying Graphics Objects in Centro assistenza e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by