What dictates whether guidata() will update handles.

2 views (last 30 days)
I have a GUI i made with GUIDE and I had to go back and add a button to it. All of a sudden I have encountered the problem where something I did in one function and used guidata(hObject,handles) wouldn't end up passing to the next function call, effectively undoing what the previous function did. I have a button that replaces a value and associated names in a listbox and does so by calling "my_update_function" and it uses a guidata() and it works just fine. I have a button that deletes a value associated names in a listbox and does so by calling the same "my_update_function". The deleting of values and replacing of values happens in the individual call back functions. "my_update_function" reconstructs the values and names that are associated with the listbox. This all was done smoothly simply using guidata() at the end of every function.
Then I tried today, weeks after I had originally made the GUI, to add an "insert" button which was effectively a combination of the replace and delete callbacks with some simple indexing changes to variables. The "insert" function calls "my_update_functions" but all of sudden guidata refuses to update the values associated with a name in the listbox stored in a separate array. It actually updates the names in the listbox, adding a new label in the listbox, but the array that is updated in "my_update_function" does not get saved by guidata. It was fixed by doing
handles=guidata(hObject);
at the end of the "insert" callback. Which occurs after "my_update_function" has already finished its job and has done a simple guidata() call at the end of its function. "my_update_function" by the way doesn't return any values so it fully relies on guidata().
What absolutely dictates whether guidata() saves the handles? All through the other functions it worked fine, but when I tried doing the same thing in another callback it simply doesn't work. I have had this problem before but fixed it more or less by getting lucky, and don't know what I did.

Answers (1)

Walter Roberson
Walter Roberson on 17 Sep 2015
guidata() updates the "master" copy of the handles structure. Any routine which has its own local copy needs to use guidata() to fetch the updated version. If you have a routine which does a read / modify / write cycle then you need to be sure that nothing else has updated the master copy between the time you did the read and the write. For the most part the defaults about Queuing Action and related properties work out, as traditionally one graphics routine was not permitted to interrupt another. But timers can interrupt graphics routines, and listeners might play a role (I do not recall what the documentation says about when listeners are called), and of course any routine you call yourself might update the structures.
This is the reason why it is necessary to design in "interface contracts". If you have interrupt routines or routines that you call explicitly, you need to know whether they have permission to change things "underneath you", and in any case where you cannot prove that nothing has changed you need to re-fetch the data or you need to use a semaphore or barrier system to ensure that you have exclusive access to the mutable resource during the critical period.

Categories

Find more on Migrate GUIDE Apps in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!