MATLAB GUI: updating variables to mat file - matlab

I have program where at the end a GUI is launched. I built it using guide. I load 4 variables from my program into 4 GUI text boxes using a mat file called n.mat (and a pushbutton feature).
In the program
n = [nuno, ndue, ntre, nquattro];
save n.mat
In the GUI interface pushbutton
% --- Executes on button press in upload.
function upload_Callback(hObject, eventdata, handles)
% hObject handle to upload (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
S = load('n.mat');
handles.v1 = S.nuno;
handles.v2 = S.ndue;
handles.v3 = S.ntre;
handles.v4 = S.nquattro;
set(handles.initial1,'String',num2str(handles.v1));
set(handles.initial2,'String',num2str(handles.v2));
set(handles.initial3,'String',num2str(handles.v3));
set(handles.initial4,'String',num2str(handles.v4));
guidata(hObject, handles);
Then I have other 4 text boxes where I change the value of the variables and save them in another mat file. I'm not sure if I'm doing this correctly.
In the program (before calling myGUI) I initialize the m vector for the updated variables.
nunof = 0;
nduef = 0;
ntref = 0;
nquattrof = 0;
m = [nunof, nduef, ntref, nquattrof];
save m.mat
In the program (after calling myGUI) I try and load the m.mat file and extract the variables from it so I can use them in some calculations further in the program.
load m.mat;
nunof = m.nunof;
nduef = m.nduef;
ntref = m.ntref;
nquattrof = m.nquattrof;
Before this, in the GUI interface 'done' button I try and save my inputs into the m.mat file like this:
function done_Callback(hObject, eventdata, handles)
% hObject handle to done (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% save the parameters to file
load('m.mat');
m = [nunof, nduef, ntref, nquattrof];
nunof = str2num(get(handles.final1,'String'));
nduef = str2num(get(handles.final2,'String'));
ntref = str2num(get(handles.final3,'String'));
nquattrof = str2num(get(handles.final4,'String'));
save('m.mat','-append');
I want to know why this isn't working and how can I change it. Thanks a lot.

You can't use save('m.mat','-append');. You're missing an option to get to append.
In order to use append you have to declare a filename, the variable and then append.
save(filename,variables,'-append')
Taken from - https://au.mathworks.com/help/matlab/ref/save.html
Also, from your code you're not redefining the variables in your m struct.

Related

How can I do side-by-side simulation of Simulink files by using for-loop in MATLAB GUI or is there another way to do it?

I want to ask how I make the following code functioning for side-by-side simulation of Simulink files, which are saved in 'PATH', by using for-loop in MATLAB GUI or if you know an alternative way to do it. After I started to run the code, nothing happened although no error message has come. Also I hope that some of you get solutions of my problem.
Thank you very much in advance!
function nightly_simulation_Callback(hObject, eventdata, handles)
% hObject handle to nightly_simulation (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
PATH = 'C:\Users\xxx\Documents\Saved_Models';
files=dir([PATH,'*.slx']);
fileNames={files.name};
fileNames=sort(fileNames);
nFiles=numel(fileNames);
selection = questdlg('Sure to start?',...
'Confirmation',...
'Yes','No','Yes');
switch selection
case 'Yes'
for i=1:nFiles
x = [PATH,fileNames{i}];
open_system(x);
sim(x);
end
case 'No'
return
end
Replace
x = [PATH,fileNames{i}];
with
x = fullfile(PATH, fileNames{i});
since otherwise a '\' is missing in the filename.
I changed my code like this:
function nightly_simulation_Callback(hObject, eventdata, handles)
% hObject handle to nightly_simulation (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
PATH = 'C:\Users\xxx\Documents\Saved_Models';
files = dir( fullfile(PATH,'*.slx') ); %# list all *.slx files
fileNames = {files.name}';
fileNames=sort(fileNames);
nFiles=numel(fileNames);
selection = questdlg('Sure to start?',...
'Confirmation',...
'Yes','No','Yes');
switch selection
case 'Yes'
for i=1:nFiles
x = fullfile(PATH, fileNames{i});
open_system(x);
sim(x);
end
case 'No'
return
end
Also it worked. Thanks for your advice!

Save data structure in existing .mat-file without nesting

I have created a simple GUI that when I press a button (SAVE), the system takes the value of some fields, calculates a certain function and saves the results in a data structure.
I would like this data structure to be external to the program, that is to say it remains at the exit of Matlab and at the next opening of the program this data structure must be available and upgradable.
To do this I used a global data variable that I save and load when needed.
The problem is that it doesn't work properly, the data structure is filled strangely.
I show you a gif that is perhaps more explanatory:
The saved structure is this:
As you can see, there is a structure within the other and not a list of elements. Why?
I would like to have a data structure that contains n elements (where n is the number of images) and each element consists of 9 fields (name, category, siftOctaves, siftLevels, siftPeak, siftEdge, numFeatures, siftFeatures, siftDescriptors).
This is a piece of code:
%% SAVE BUTTON
function pushSiftSave_Callback(hObject, eventdata, handles)
% hObject handle to pushSiftSave (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global data;
try
% Vector of string = name of all possible images
imgs = createListOfImages('../img/');
% Get selected image
imgName = get(handles.listbox, 'Value');
imgPath = strcat('../img/', imgs(imgName));
imgPath = imgPath{1};
I_or = imread(imgPath);
I = single(rgb2gray(I_or));
% Get some parameters enter by user
[siftOctaves, siftLevels, siftPeak, siftEdge] = takeSiftParameters(handles.editSiftOctaves, handles.editSiftLevels, handles.editSiftPeakTh, handles.editSiftEdgeTh, I_or);
% Sift function
[f, d] = vl_sift(I, 'Octaves', siftOctaves, 'Levels', siftLevels, 'PeakThresh', siftPeak, 'EdgeThresh', siftEdge);
% Number of features
perm = randperm(size(f, 2));
numFeatures = size(perm, 2);
% Check if file exists
if exist('../data/data.mat', 'file') == 2
data = load('../data/data');
else
data = struct;
end
% Insert information in data structure
data = saveSiftInformation(data, imgs, imgPath, siftOctaves, siftLevels, siftPeak, siftEdge, f, d, numFeatures);
catch
ErrorMessage = lasterr;
msgbox(ErrorMessage);
disp(ErrorMessage);
end
function [data] = saveSiftInformation(data, imgs, imgPath, siftOctaves, siftLevels, siftPeak, siftEdge, features, descriptors, numFeatures)
imgPath = imgPath(8 : end);
% Find index of image
i = find((ismember(imgs, imgPath)));
% Update data structure
data(i).name = imgPath;
data(i).category = imgPath(1 : end-6);
data(i).siftOctaves = siftOctaves;
data(i).siftLevels = siftLevels;
data(i).siftPeak = siftPeak;
data(i).siftEdge = siftEdge;
data(i).numFeatures = numFeatures;
data(i).siftFeatures = features;
data(i).siftDescriptors = descriptors;
% Save data
save('../data/data', 'data');
end
%% SAVE & QUIT BUTTON.
function pushQuit_Callback(hObject, eventdata, handles)
% hObject handle to pushQuit (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global data;
assignin('base', 'data', data);
Thanks!
The problem you're facing is generated when you load the data.mat file.
Also, using data as the name of variable reurned by load contributes to generating confusion.
The instruction
data = load('../data/data')
reads the data.mat and stores the "data" it contains in a struct named data therefore, your struct is actually a filed of the struct data returned by load.
You can test it by setting a breakpoint just after the load call and inspecting the varialbe data.
You can fix the problem by extracting the data field from the structure when loading the .mat file.
if(exist('data.mat', 'file') == 2)
% data = load('data');
tmp = load('data');
data=tmp.data
else
data = struct;
end
Hope this helps,
Qapla'
By using the output variable of the load function you are storing the variable data from your .mat-file to a struct called data - so it gets nested. Just use load without any output and it will work.
if exist('data.mat', 'file') == 2
%// data = load('data'); % does not work!
load('data'); % does work!
else
data = struct;
end
data(1).a = 42;
data(2).a = 3;
data(1).b = 41;
data(2).b = 4;
%// make sure you just store what you want to store, in this case "data"
save('data.mat','data')
Also I would avoid declaring data a global variable. Instead you could use the fact, that all functions of your GUI are part of the same figure window and therefore have the figure handle available:
hFig = gcf;
It is further allowed to add dynamic properties do your instance of figure, so just store your data in the figure handle itself:
hFig = gcf;
addprop(hFig,'globalData')
data = struct;
hFig.globalData = data;
% ...
and in the next function you just do:
data = hFig.globalData

How to transfer data from one gui matlab to edit box of another gui matlab

I have 2 guis in matlab which are named main and sub. I do some calculation on a image by push button in subgui and want to transfer the results (handles.sh and handles.sv) to edit box of main gui and these results should be showed in separate lines in edit box. I used setappdata and getappdata but it doesn't work and it doesn't show any thing or more probably I made a mistake.
edit box callback of main gui
function edithistory_Callback(hObject, eventdata, handles)
% hObject handle to edithistory (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles.sh = getappdata(0,'horizontal');
set(hObject,'String',num2str(handles.sh));
handles.sh = getappdata(0,'vertical');
set(hObject,'String',num2str(handles.sv));
push button callback of subgui
Bw = im2bw(handles.D);
s = regionprops(Bw, handles.D, 'Centroid');
handles.sx = round(s.Centroid(1));
handles.sy = round(s.Centroid(2));
handles.roi = handles.roi/2;
i = (handles.sx-((handles.roi)-1)):(handles.sx+ handles.roi);
j = (handles.sy-((handles.roi)-1)):(handles.sy+ handles.roi);
ROI = (handles.D(i,j));
ROI = (2^16)-ROI;
avg = sum(ROI(:))/((2*handles.roi).^2);
profileh1 = (handles.D(handles.sx,:));
profileh = (2^16-profileh1);
profileh(1)= profileh(2);
FieldSizeh = profileh(profileh>=avg*0.5);
FieldSizeh(:) =avg;
handles.sh = (size(FieldSizeh,2)*0.25);
setappdata(0,'horizontal',handles.sh);
profilev1 = handles.D(:,handles.sy);
profilev = (2^16-profilev1);
profilev(1)= profilev(2);
FieldSizev = profilev(profilev>=avg*0.5);
FieldSizev(:)=avg;
handles.sv = (size(FieldSizev,1)*0.25);
setappdata(0,'vertical',handles.sv);

How to get selected values from listbox within a dialog box

I have used the following code in a GUI to open a listbox in a dialog box when a pushbutton is pushed by the user:
% --- Executes on button press in selectdata.
function selectdata_Callback(hObject, eventdata, handles)
% hObject handle to selectdata (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
X = getappdata(0,'XValue');
Y = getappdata(0,'YValue');
A = [X,Y];
str = num2str(X);
[s,v] = listdlg('PromptString','Select Initial & Final Wavelength:','SelectionMode','multiple','ListString',str);
selected_values = get(hObject,'value');
I am trying to get the the values selected in the listbox but I am having difficulty in doing so as I keep getting
selected_values =
1
in the comand window, which I'm presuming just means it is true.
Does anyone have an idea on how to get the selected values from the listbox in the dialog box?
The index of the selected value will be s. The value will be str{s} or str(s,:), depending on whether you have stored str as a character array or a cell array of strings.
get(hObject,'value') here is not doing what you intend - hObject refers to the pushbutton you pressed, not the listdlg, so it's getting the value of the pushbutton itself.

How to read multiple lines by individual in an edit text with a value of Max=5 in Matlab?

I have in my gui an edit text field that accepts multiple lines with a Max value of 5, and i can't find a way to display a matrix with the input values...something like this:
m=[m(1) m(2) m(3) m(4) m(5)];
set(handles.show,'string',m)
how can i store the values in the calculate callback..every time i run this, it brings me an error..
function masa_Callback(hObject, eventdata, handles)
% hObject handle to masa (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
%h_edit is the handle to the edit box
m=str2double(get(hObject,'String'));
function calculate_Callback(hObject, eventdata, handles)
% hObject handle to agregarm (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
f = str2double(get(h_fuerza,'string')); %h_edit is the handle to the edit box
m = str2double(get(h_masa,'string')); %h_edit is the handle to the edit box
[row, column] = size(m);
for i = 1:row
eval(m{i,:}) %evaluate each line as in MATLAB command prompt
end
I have the masa_callback,rigidez_callback and fuerza_callback i try to read the user input in the edit text box...so i want to pass those values to the calculate_callback as an array to perform certain operations according to the value of n...the error that i am getting is that when for example n=2, i add two values in the masa_callback column and fuerza_callback and 3 values in the rigidez_callback, those values are passed to the case n==2, and when my program tries to display for example the matrix m, it displays all the values i enter together in the spaces of m(1) and m(2)...i want to put only each separated value, not joined together!...How can i fix this,, i believe that is whith an array and a loop but i dont know how, and how to pass the array values to the equation to perform operations(as numbers) and display it as string
To fix the problem with the input (assuming you have your data in some cell array, and that handles.show refers to a text box), use strvcat:
someCellArray = {'a','b'};
m = strvcat(someCellArray{:});
set(handles.show,'string',m)
Your problem stems from the line
m = str2double(get(h_masa,'string'));
You do not want to convert the string to double.
Since the String property actually returns a multiline string, you have to modify your code like this:
m = get(h_masa,'String');
nRows = size(m,1);
for iRow = 1:nRows
eval(m(i,:));
end