Index exceed matrix dimensions in GUI
Show older comments
Hye i have problem with this error, here is my code in pushbutton1_callback:
global r;
[a, b]=uigetfile('.bmp');
img=imread([b a]);
imshow(img,'Parent',handles.axes1);
if (a =='1.bmp')
d = r(1,:);
elseif (a =='2.bmp')
d = r(5,:);
elseif (a =='3.bmp')
d = r(9,:);
end
and the error is:
--> Index exceeds matrix dimensions.
-->Error in SystemDemo1>pushbutton1_Callback (line 86)
d = r(1,:);
--> Error in gui_mainfcn (line 95)
feval(varargin{:});
-->Error in SystemDemo1 (line 42)
gui_mainfcn(gui_State, varargin{:});
-->Error in matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)SystemDemo1('pushbutton1_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback
and r is actually a variable in matlab workspace. but i want the contents in r which the value is in double to be used in my gui. So, thats why im using global. Hope any of you guys could help me as im new in using function in GUI and it seems complicated/hard for me because im never used it. Any advice or help will be really appreciated. Thank you so much.
5 Comments
Rik
on 10 May 2018
Did you set the variable in your normal workspace as a global as well?
Also, try to find an alternative to your use of a global (like setappdata (and getappdata), or changing the way your function starts so you can supply it as an input and get it saved with guidata), or make the name of that global very descriptive and let it contain the name of the function. If you do that, you are not likely to have your variable collide with another global from another piece of code.
Nurul Atifah
on 10 May 2018
Jan
on 10 May 2018
Do not compare char vectors by the elementwise comparison ==, but by strcmp:
% if a =='1.bmp' replace by:
if strcmp(a, '1.bmp')
Dennis
on 10 May 2018
There are a quite a few alternatives to global variables. If you want to use globals you need to declare said global in every function/script you are using.
For further information about passing data between callbacks please have a look here: https://de.mathworks.com/help/matlab/creating_guis/share-data-among-callbacks.html
In your case i suggest to either pass r as additional input to your function
function pushbutton1_callback(hObject,~,r)
and when you create your pushbutton:
Callback,{@pushbutton1_callback,r}
or use setappdata/getappdata like Rik Wiselink suggests:
After you created your pushbutton:
setappdata(handles.pushbutton1,'r',r);
In your function:
r=getappdata(hObject,'r');
I do not know if hObject and handles.pushbutton1 are correct in your case since those parts of your code are missing.
Nurul Atifah
on 10 May 2018
Edited: Nurul Atifah
on 10 May 2018
Answers (1)
Ameer Hamza
on 10 May 2018
Edited: Ameer Hamza
on 10 May 2018
Have you declared r as global in command window by running
global r
You need to run global r both in the command window and your app code. Another way is to use evalin() to get value from base workspace directly in GUI without using global. Use it like this
r = evalin('base', 'r');
Note that all of these options are unrecommended. See Here: https://www.mathworks.com/matlabcentral/answers/304528-tutorial-why-variables-should-not-be-named-dynamically-eval. You should consider @Rik's suggestion to improve the reliability of your code.
15 Comments
Nurul Atifah
on 10 May 2018
Dennis
on 10 May 2018
Try this:
function pushbutton1_Callback(hObject, ~ , ~)
r=getappdata(hObject,'r');
[a, b]=uigetfile('.bmp');
img=imread([b a]);
imshow(img,'Parent',handles.axes1);
if strcmp(a,'1.bmp')==1
d = r(1,:);
elseif strcmp(a,'2.bmp')==1
d = r(5,:);
elseif strcmp(a,'3.bmp')==1
d = r(9,:);
end
In your other script/function you should have two lines like this:
handles.pushbutton1=uicontrol('Style','pushbutton','String','My Pushbutton','Callback',{@pushbutton1_Callback}); %add/edit string/position/parent...if needed
setappdata(handles.pushbutton1,'r',r)
Nurul Atifah
on 11 May 2018
Edited: Nurul Atifah
on 11 May 2018
Dennis
on 11 May 2018
You have only shared your callback function. The setappdata and uicontrol lines need to go in your gui/guide script or function where you create your button.
Do you need to load your data into base workspace or can you load it inside your gui? You could aswell pass r as function input when you call your gui.
Rik
on 11 May 2018
Why don't you load the mat file when you start the GUI in the openingFcn?
Nurul Atifah
on 11 May 2018
Dennis
on 11 May 2018
my_data = load('filename.mat','-mat'); %returns a structure
Nurul Atifah
on 11 May 2018
Edited: Nurul Atifah
on 11 May 2018
Nurul Atifah
on 11 May 2018
@Nurul Atifah: Using a GUI to magically "poof" data into the base workspace and then perform operations on it only causes problems, and makes code complex and buggy. You should simply load the data into some function workspace within the GUI (e.g. a callback) and the pass it around the GUI using the methods explained to you (e.g. guidata). Forget about the base workspace. Learn to love function workspaces.
"there is another way to load my .mat in the workspace so i could use it during operating my GUI"
You don't need to spam that data into the base workspace (and it would be bad code that does that). What you load it is already in one of the GUI function workspaces, so you can simply work with it directly inside the GUI.
You should not magically make variables appear in other workspaces using global, evalin or assignin, unless you want to force yourself into writing slow, complex, buggy code that is hard to debug.
Nurul Atifah
on 11 May 2018
my bad, you wont need
handles.pushbutton1=uicontrol('Style','pushbutton','String','My Pushbutton','Callback',{@pushbutton1_Callback}); %add/edit string/position/parent...if needed
that line actually creates a button, i falsely assumed guide would include these lines.
Just add
my_data = load('filename.mat','-mat'); %returns a structure
if isfield(my_data,'r')==1 %checks if r exists in my_data
r=my_data.r; %gets r from structure
setappdata(handles.pushbutton1,'r',r) %stores r,
end
to your OpeningFcn
If you need more than only r you can pass the entire structure with setappdata.
1.) You could create a button to load data, but if you need to load data only once it wont be necessary
2.)yes, you wont see any variables in your base workspace, but as long as you pass them around your gui properly you can use them.
3.) the variables are actually in the function workspace
4.) no please do not use globals :)
- I have no idea what that means. However it is your GUI design, so you can load data whenever you want.
- There is not such thing as " the workspace". The base workspace is just one of them, every function has its own workspace. Your GUI is full of functions, ergo it is full of workspaces that you can load data into (and pass data between). Read more here: https://www.mathworks.com/help/matlab/matlab_prog/base-and-function-workspaces.html
- Again, there is no such thing as " the workspace". When you load your data into the workspace of a function then that is where the data is. You do not need to magically "poof" everything into the base workspace (unless you want to write spaghetti code).
- Do not use global variables. As the others have already written, use guidata, or nested functions, or setappdata & getappdata.
Nurul Atifah
on 11 May 2018
Edited: Nurul Atifah
on 11 May 2018
Dennis
on 11 May 2018
Yes, you can pass other variables or even the entire struct.
setappdata(handles.pushbutton1,'my_data',my_data)
In the code you have shown you are passing p twice and dont pass r
Does your callback function start like this:
function pushbutton1_Callback(hObject,eventdata,handles)
Categories
Find more on Whos 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!