How to pass arrays to and from a GUI?

19 visualizzazioni (ultimi 30 giorni)
Eric H.
Eric H. il 26 Ott 2011
I am relatively new to MATLAB and just starting to try to use GUIs. Maybe I'm going about this all wrong, but I want to run a GUI from a MATLAB program. I want to pass arrays of X and Y values to the GUI, to plot and manipulate the data in the GUI, and then return the manipulated X and Y values plus certain other variables that are generated in the GUI back to the program. I cannot for the life of me figure out how to pass arrays and other variables between the program and the GUI. What am I missing?
  1 Commento
Image Analyst
Image Analyst il 27 Ott 2011
Do you want to pass variables just when you call up the GUI for the first time, or also after you've already call it up? Because it makes a difference. If it's just when you call it, you can do it via the arg list.

Accedi per commentare.

Risposte (8)

Image Analyst
Image Analyst il 27 Ott 2011
Eric: Just pass them in via the argument list when you call it in your main routine:
test_2(mainVal1, mainVal2, mainVal3, mainVal4); % or whatever
Inside your test_2's OpeningFcn function, just extract them from the varargin:
function test_2_OpeningFcn(hObject, eventdata, handles, varargin)
guiVal1 = varargin{1};
guiVal2 = varargin{2};
guiVal3 = varargin{3};
guiVal4 = varargin{4};
Then use the link Walter gave you to learn how to share those values amongst the other functions in your GUI file that may need to use them. You might also look into the deal() function.
  3 Commenti
John
John il 23 Lug 2013
I want to show an image within my GUI. I am using GUIDE, so I created an axis where the image can go. Then I created a "CreateFcn" for that axis, which is where I am putting my imshow command. However, that function seems to be executing before my GUI's OpeningFcn. So, although I set one of my varargin values to handles.I within the OpeningFcn, it happens after my imshow(handles.I) within my CreateFcn. Any suggestions? Is the CreateFcn for my axis the wrong function to have my imshow(handles.I)?
Image Analyst
Image Analyst il 24 Lug 2013
No, that's not the right place. Put it in the OepnFcn function for your GUI, or else in a callback function of a listbox or push button.

Accedi per commentare.


Walter Roberson
Walter Roberson il 26 Ott 2011

Naz
Naz il 27 Ott 2011
This is how I do it:
x=evalin('base','X');
where x is my variable in GUI, 'base' assumes WorkSpace and X is a variable that will be read from workspace to the GUI. Similarly, you can pass the variable to the workspace:
assignin('base', 'X', x)
where x is the GUI variable and X is a future variable in workspace.

Alex
Alex il 26 Ott 2011
I've started using a class based system to implement Gui's and passing information between.
The following little class relies on an existing GUI with a single button and text box. Each press of the button increments the value in the text box by 1. The data is being passed is an illusion because the class actually contains everything from the beginning.
The closerequest function is used so that if the gui is closed before the memory is cleared, the class is cleaned up.
classdef myclass < handle
%class properties that will eb shared over the entire class - these cannot be seen or changed from outside of the class
properties (Access = Private)
%pointer to the gui
gui_handle = [];
%generic counter
my_int = 0;
end
methods
%class constuctor
function this = myclass()
%create the gui and store the handle
this.gui_handle = guihandles("name of gui");
%set the callback fcn
set(this.gui_handle.button, 'callback', @(src, event) Btn_callback (this, src, event));
%set the close-request function so the class gets a signal when the gui closes
set(this.gui_handle.figure1, 'closerequestfcn', @(src, event) Close_fcn (this, src, event));
end
%class deconstructor
function delete(this)
%gui exists
if(isempty(this.gui_handle))
set(this.gui_handle.figure1, 'closerequestfcn', '');
delete(this.gui_handle.figure1);
this.gui_handle = [];
end
function Close_fcn(this, src, event)
delete(this);
end
function this = Btn_callbakc(this, src, event)
this.my_int = this.my_int + 1;
set(this.gui_h.my_text_box, 'string', sprintf('%i',this.my_int));
end
end

Eric H.
Eric H. il 27 Ott 2011
I appreciate the responses, but unfortunately I am not getting it. Here is an example of what I want to do - with the very awkward use of writing and reading from a mat file to pass the information. I cannot figure out how to do it properly. Thanks.
Here is the main program
x = linspace(-50,50,101);
y = -10*exp(-x.^2/50).*x ;
save('input.mat','x','y');
test_2;
pause;
load('output.mat');
and here is the GUI
function varargout = test_2(varargin)
% TEST_2 MATLAB code for test_2.fig
% TEST_2, by itself, creates a new TEST_2 or raises the existing
% singleton*.
%
% H = TEST_2 returns the handle to a new TEST_2 or the handle to
% the existing singleton*.
%
% TEST_2('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in TEST_2.M with the given input arguments.
%
% TEST_2('Property','Value',...) creates a new TEST_2 or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before test_2_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to test_2_OpeningFcn via varargin.
%
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
% instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help test_2
% Last Modified by GUIDE v2.5 26-Oct-2011 17:36:16
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @test_2_OpeningFcn, ...
'gui_OutputFcn', @test_2_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before test_2 is made visible.
function test_2_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to test_2 (see VARARGIN)
% Choose default command line output for test_2
handles.output = hObject;
% Update handles structure
load('input.mat');
handles.x = x;
handles.y = y;
plot(handles.x,handles.y);
guidata(hObject, handles);
% UIWAIT makes test_2 wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = test_2_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
% --- Executes on slider movement.
function slider1_Callback(hObject, eventdata, handles)
% hObject handle to slider1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
factor = get(hObject,'Value');
handles.y2 = factor*handles.y;
plot(handles.x,handles.y,handles.x,handles.y2);
x2 = handles.x;
y2 = handles.y2;
save('output.mat','x2','y2','factor');
% --- Executes during object creation, after setting all properties.
function slider1_CreateFcn(hObject, eventdata, handles)
% hObject handle to slider1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor',[.9 .9 .9]);
end
The GUI reads x and y values from the mat file, multiplies the y variable by a factor determined by the slider, and writes the modified variables together with the factor back to a second mat file which is then read by the main program. I would like to pass variables both ways without having to write/read mat files.

Walter Roberson
Walter Roberson il 27 Ott 2011
In slider1_Callback instead of your current lines
x2 = handles.x;
y2 = handles.y2;
save('output.mat','x2','y2','factor');
substitute
guidata(hObject,handles);
In your main program, in place of your current lines
test_2;
substitute
test2fig = test_2;
Then after the pause line that follows, for the "load" line, substitute
handles = uidata(test2fig);
and then extract handles.y2 and so on.
My main concern is that you have not defined a distinct "I'm done" in test_2, so the pause() that you use is not likely to work properly. Remember, you slider callback will stay active and will update the values many times over the course of a single slider drag. If there is no way for the user to signal they are done, the main routine may attempt to continue before anything has been done, or may sit waiting forever (or until the user closes test_2, but that would be a bad idea all of the data is being dangled off of something that is deleted if test_2 is closed.)

Eric H.
Eric H. il 27 Ott 2011
Walter, Thanks againg for your help. I almost have this working. Here is a new version of the code. I have tried to add the "Close" button. I am getting the "handles" variables back into the main program "test" but they are the original values, not the updated values. So handles in the main program does not contain handles.z If I debug at "1" in "test_gui" all of the correct info is in handles. So it looks like "handles" is being passed back to "test" as soon as "test_gui" is called and not when "test_gui" is closed. Any thoughts??
x = linspace(-50,50,101);
y = -10*exp(-x.^2/50).*x ;
test_guifig = test_gui(x,y);
handles = guidata(test_guifig);
and
function varargout = test_gui(varargin)
% TEST_GUI MATLAB code for test_gui.fig
% TEST_GUI, by itself, creates a new TEST_GUI or raises the existing
% singleton*.
%
% H = TEST_GUI returns the handle to a new TEST_GUI or the handle to
% the existing singleton*.
%
% TEST_GUI('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in TEST_GUI.M with the given input arguments.
%
% TEST_GUI('Property','Value',...) creates a new TEST_GUI or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before test_gui_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to test_gui_OpeningFcn via varargin.
%
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
% instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help test_gui
% Last Modified by GUIDE v2.5 27-Oct-2011 15:48:26
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @test_gui_OpeningFcn, ...
'gui_OutputFcn', @test_gui_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before test_gui is made visible.
function test_gui_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to test_gui (see VARARGIN)
% Choose default command line output for test_gui
handles.output = hObject;
% Plot input data;
handles.x = varargin{1};
handles.y = varargin{2};
plot(handles.x,handles.y);
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes test_gui wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = test_gui_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
% --- Executes on slider movement.
function factor_slider_Callback(hObject, eventdata, handles)
% hObject handle to factor_slider (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
handles.factor = get(hObject,'value');
handles.z = handles.factor*handles.y;
plot(handles.x,handles.y,handles.x,handles.z);
disp('slider');
disp(handles.factor);
guidata(hObject,handles);
% --- Executes during object creation, after setting all properties.
function factor_slider_CreateFcn(hObject, eventdata, handles)
% hObject handle to factor_slider (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor',[.9 .9 .9]);
end
% --- Executes on button press in close_button.
function close_button_Callback(hObject, eventdata, handles)
% hObject handle to close_button (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
disp('Closing test_gui GUI');
% guidata(hObject,handles);
1
close(handles.figure1);
% --- Executes during object creation, after setting all properties.
function close_button_CreateFcn(hObject, eventdata, handles)
% hObject handle to close_button (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
  1 Commento
Walter Roberson
Walter Roberson il 28 Ott 2011
When you change the handles structure in a callback, you should use guidata(hObject,handles) to cause the global copy to be updated. Then, at any point in anyother routine where you expect that the handles structure might have been updated since the last time you looked at it, you need to use
handles = guidata(hObject);
in order to pull in the updated version.

Accedi per commentare.


Alex
Alex il 28 Ott 2011
I think the problem you are talking about is with the function call to "guidata(test_gui)".
This function is not a pass by reference, as in it does not keep a constant updated value of the data.
I ran your code (with a quick gui I made myself) and did the following. 1. created the gui. 2. ran g = guidata cmd - the result had no z data 3. adjusted the bar - the graph updated 4. looked at the variable g, containing the guidata - no z data. 5. ran g = guidata again, now the z data shows up.
What are you trying to specifically accomplish with this example? The factor and z data variables are not used but within the factor_slider callback, and therefore are not needed to be recorded.

Categorie

Scopri di più su Migrate GUIDE Apps in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by