Integrating multiple callbacks in a GUI window

18 vues (au cours des 30 derniers jours)
Aaron Smith
Aaron Smith le 10 Avr 2017
Commenté : Aaron Smith le 3 Mai 2017
I have been trying for an extended period of time to share data among the apps of a GUI window. I have several codes to format data and navigate through but each time i attempt to create a common code between callbacks I generate an error. I have looked at the MathWorks page for sharing data among callbacks with no luck as of yet. At the moment I need to create a window with an axis, a push button and a slider so that i can test if my slider code is working.
function varargout = push_slider(varargin)
% PUSH_SLIDER MATLAB code for push_slider.fig
% PUSH_SLIDER, by itself, creates a new PUSH_SLIDER or raises the existing
% singleton*.
%
% H = PUSH_SLIDER returns the handle to a new PUSH_SLIDER or the handle to
% the existing singleton*.
%
% PUSH_SLIDER('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in PUSH_SLIDER.M with the given input arguments.
%
% PUSH_SLIDER('Property','Value',...) creates a new PUSH_SLIDER or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before push_slider_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to push_slider_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 push_slider
% Last Modified by GUIDE v2.5 06-Apr-2017 13:10:23
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @push_slider_OpeningFcn, ...
'gui_OutputFcn', @push_slider_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 push_slider is made visible.
function push_slider_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 push_slider (see VARARGIN)
% Choose default command line output for push_slider
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes push_slider wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = push_slider_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 button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
guidata(hObject, handles);
myFolder = uigetdir('C:\Users\c13459232\Documents\MATLAB'); % Generate command window to choose a folder
if ~isdir(myFolder) % if the directory is not a valid path
errorMessage = sprintf('Error: the following folder does not exist: \n%s', myFolder); % print this error message
uiwait(warndlg(errorMessage)); % block the execution of program and wait to resume
return;
end
outFolder = fullfile(myFolder, 'output'); % build full file name from parts in folder 'Output'
mkdir(outFolder); % create folder
filePattern = fullfile(myFolder, '*.asc'); % Call all files with '.asc' from the chosen folder
Files = dir(filePattern); % list folder contents
finishCell = cell(length(Files));
for k = 1 : length(Files) % for all files files in the folder
baseFileName = Files(k).name;
FileName = fullfile(myFolder, baseFileName);
fid = fopen(FileName); % open the file from chosen folder
Cell = textscan( fid, '%d', 'delimiter', ';'); % scanning data from files
fclose(fid); % close file from chosen folder
Data = cell2mat(Cell); % convert the cell data to matrix
N = 1024; % Number of numbers per row
skip = 2;
Finish0 = reshape(Data, N, [])'; % reshape the data into the correct format
Finish1 = Finish0(1:skip:end, 1:skip:end);
finishCell{k} = Finish1;
end
% --- 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
SliderValue = get( handles.slider, 'value');
x = SliderValue;
z = (SliderValue - 1);
Value = contourf(finishCell{x,1});
PreviousValue = contourf(finishCell{z,1});
% --- 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
I'm not sure how I can specify that the finishCell value created by the push button is what will be navigated through using the slider. Honestly any tips that anyone can provide would be greatly appreciated as staring at this code and mathworks pages has led me here as a last resort.
  3 commentaires
Adam
Adam le 10 Avr 2017
Modifié(e) : Adam le 10 Avr 2017
You can't have looked at the Mathworks page on sharing data among callbacks for very long if you opted to not even try any of the options it gives to share 'finishCell' between your pushbutton callback and the slider callback!
gives numerous options, none of which you have tried in the code you post. Personally I generally use the guidata option, but they all work, in certain situations.
Aaron Smith
Aaron Smith le 10 Avr 2017
Each cell of the finishCell is a matrix that will be plotted using contourf. Then the slider will generate the next contourf plot when the arrow is pushed.
With regards to the guidata, I have tried using it, as well as the GatherAndUpdate method and I can not get them to work. The reason I didn't have them here in the code is to avoid confusion

Connectez-vous pour commenter.

Réponses (1)

Jan
Jan le 10 Avr 2017
The guidata method is straight forward:
function OpeningFcn(hFigure, EventData, handles)
handles.Data = []; % Initialize properly
handles.Value = [];
guidata(hObject, handles); % Store ucrrent value in the figure
function CallbackXYZ(hObject, EventData, handlesFromInputs)
handles = guidata(hObject); % Get current value from figure
...
handles.Data = rand; % any modifications
disp(handles.Value); % any access
guidata(hObject, handles); % Store handles struct in the figure again
Now the handles struct is available and uptodate in each callback.
  13 commentaires
Adam
Adam le 3 Mai 2017
You shouldn't need any subfunctions to share data, just attach it to the handles structure.
I would strongly advise more meaningful variable/field names though as yours are extremely confusing.
You have a field on your handles structure called 'pushbutton' which looks like it is a cell array from the way you access it. Then you have another called 'slidervalue' which looks like it is a graphics object handle to a contour plot.
In the case of 'Data', it is up to you whether you store it or not. You could just access it directly in your pushbutton4 (again, give it a more meaningful tag!) callback as
Data = handles.pushbutton{ get( handles.slider1, 'value' ), 1 };
I used slider1 here as that seems to make sense although in your code you use handles.slider in slider1_Callback. I don't know if this is just a typo, but it is odd otherwise to access the value of a totally different slider in your slider callback!
Aaron Smith
Aaron Smith le 3 Mai 2017
The pushbutton handle is a cell array that is made when i open files and reformat them into a cell array. Each of these cells can then be plotted by the slider callback.
From my reading of information on handles, it says that if there is a variable inside a function that is shared with multiple callbacks, a subfunction should be created with the handles structure so that the variable can be accessed by other callbacks.
% --- 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
handles = guidata(hObject);
function myData(handles)
SliderValue = get( handles.slider, 'value');
Data = (handles.pushbutton{SliderValue,1});
handles.Data = Data;
end
handles.slidervalue = contourf(Data);
guidata(hObject, handles);
end
Now I can share the data variable with other callbacks using the handles structure

Connectez-vous pour commenter.

Catégories

En savoir plus sur Migrate GUIDE Apps dans Help Center et File Exchange

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by