views:

141

answers:

2

I am building a straightforward MATLAB gui using GUIDE. I have a listbox of items. Most of the time, it works as expected, but sometimes (usually after I edit the figure with GUIDE) populating the listbox causes it to disappear, along with this message:

Warning: single-selection listbox control requires a scalar Value
Control will not be rendered until all of its parameter values are valid 

This behavior defies debugging! When I step through, it works as expected (I suspect it is a kind of thread race or something). Furthermore, it usually goes away after restarting the MATLAB environment, under identical conditions.

All documentation found on this error refer to previous/ancient versions of MATLAB (I am using R2010a).

Any ideas or information on this subject would be greatly appreciated!


EDIT: thanks to Mikhail, I seem to have solved the problem. I am posting my code here for future reference.

After lots of debug printing and wild clicking, I found that sometimes when you ask the listbox what is selected, you get an empty result. This and other problems made things go haywire. I moved all of my writing interactions to the listbox into a centralized function, and I wrote some testing code to ensure that things stay the way they should.

Please note that this has been tested in my own environment (on R2010a) and not extensively. Also, the code is a bit redundant, but it made me feel good anyway. (ie. itemcount can't be less than 0 ...)

function ensure_listbox_ok(handles)

%check to make sure it does not suck - ask what it has
thestrings = get(handles.listbox_files, 'String');
selection = get(handles.listbox_files, 'Value');

itemcount = length(thestrings);

betterselection = selection;

if(itemcount <= 0)
    betterselection = 1;
else
    if(selection > itemcount)
        betterselection = itemcount;
    end
end

%never use zero!!!! even if 1 is out of bounds.
if(isempty(betterselection) || betterselection <= 0)
    betterselection = 1;
end

%uncomment for debug logging
%display(['Was: ' num2str(selection) ', cleaned: ' num2str(betterselection)]);

%update if we are out of bounds.
if(isempty(selection) || betterselection ~= selection)
    set(handles.listbox_files, 'Value', betterselection);
end
+2  A: 

This is a known programming-error and it has nothing to do with race condition!

This is how it should work:

For Popup and single-selection List string property must be not-empty, i.e. have some content. But it is empty by default therefore it must be always defined.

In Popup displayed (in List highlighted) item is defined by two properties string (as cell array of strings) and value (which is 1 by default).

Taking first element in an empty array obviously does not work, therefore the control can not be rendered!

Your Listbox control is single-selection - its properties min < max and value is scalar and >0. Listbox (but not Popup) can be multi-selection if property min > max, in this case value can be an array (which implies also empty) and empty string will not cause problems.

Read MATLAB Help for uicontrol properties string, value, min, max, listboxtop

In praxis

  • You say it manifests itself after editing with GUIDE. GUIDE creates code-behind. After editing old code-behind sometimes remains in place.
  • Sometimes MATLAB is sensitive to the order inside one statement, i.e. set(hlist, 'value', 2, 'string', {'aa','bb'}) sets naively value to 2 before string is long enough and invalidates uicontrol.
  • MATLAB is buggy, every new version twice a year removes old and brings new bugs. If you are sure that debugging mode works not as it should then it is a case for MATLAB support. I have same code running as m-code, p-code and compiled exe - same code behaves differently, mainly in how GUI works.
Mikhail
Hi Mikhail, thanks for answering! I still would like more information. You say listbox is empty by default but must NOT be empty ... how does that work?? How come it works for me sometimes, but not all the time? How come I cannot debug this error? I am fairly sure I follow all the guidelines for this uicontrol, and yet it SOMETIMES crashes on me, under identical conditions. Thank you for helping!
eli
Thank you for the great tips. You are obviously very experienced with this type of thing. You pointed me in the right direction, and now I do listbox things much more carefully. I am posting another answer with my code, but you get the prize =)
eli
+1  A: 

In my experience, this error most often occurs when the value property is larger than the number of entries in the listbox. Thus, whenever you repopulate the listbox, you should update the value property - set it to 1 for safety reasons.

Other than that, check the excellent comments by @Mikhail.

Jonas