GUI wait for uitable callback to write data to variable

5 Ansichten (letzte 30 Tage)
Justin Ruiz
Justin Ruiz am 6 Sep. 2019
Bearbeitet: Stephen23 am 10 Sep. 2019
GUI has pushbutton that launches Setup function. Within the setup function, if a .mat file is found, the user has a choice to edit the data. If they decide 'Yes', a uitable is launched containing data previously entered so that it could be amended. Using the DeleteFcn callback, I wanted to capture the new data and rewrite it back into the .mat file. However, it states that the variable is undefined. I know this is a GUI vs function workspace issue but I'm not sure how to overcome it. Below is the sample code of relevant functions.
From GUI:
function button2_Callback(hObject, eventdata, handles)
Setup();
Relvant Setup Function code:
i=1;
while(i<=size(t,1)) %Enters in tablename value into data table if not empty, should never overwrite other values!
if (~isempty(t(i,12)))
msg = sprintf('Would you like to adjust parameters for %s?',string(t(i,12)));
opts.Interpreter = 'tex';
opts.Default = 'No';
dec = questdlg(msg,'Choice','Yes','No',opts);
switch dec
case 'Yes'
f = figure('Name','Couch Parameters (cm)');
% cBack = @(src,evt) cBack(src,evt,0,f);
tabs = cell2mat(t(i,1:10));
uit = uitable(f,'Data',tabs,'Position',[10 100 700 200],'DeleteFcn','tbldatamd = MyDeleteFcn(gcbo)'); %BOLD
uit.ColumnName = {'Absolute VRT','Absolute LNG','Absolute LAT','VRT Offset','LAT Offset','BB2 LNG Offset','BB3 LNG Offset','BB4 LNG Offset','BB5 LNG Offset','BB HU'};
uit.RowName = {char(t(i,12))};
uit.FontSize=10;
set(f, 'MenuBar', 'none');
table_extent = get(uit,'Extent');
set(uit,'Position',[1 1 table_extent(3) table_extent(4)])
figure_size = get(f,'outerposition');
desired_fig_size = [figure_size(1) figure_size(2) table_extent(3)+15 table_extent(4)+55];
set(f,'outerposition', desired_fig_size);
movegui('center');
uit.ColumnEditable = true;
uiwait(f); %BOLD
t(i,1:10) = num2cell(tbldatamd); %BOLD
end
end
i = i+1;
MyDeleteFcn
function data = MyDeleteFcn(t)
data = get(t,'Data');
I bolded the relevant sections that I believe are causing the issue. Any help appreciated.

Antworten (1)

Adam Danz
Adam Danz am 6 Sep. 2019
Bearbeitet: Adam Danz am 6 Sep. 2019
Fixing the callback definition and function
To start, the callback function cannot have an output. Although character vector definitions are accepted (as Walter points out in the comments below), a better way to define the callback function is to use a handle or cell array.
uit = uitable(f,'Data',tabs,'Position',[10 100 700 200],'DeleteFcn','tbldatamd = MyDeleteFcn(gcbo)');
%______________________________%
The DeleteFcn comes with two built-in inputs that are the first two inputs to your callback function. The first is the object handle to whatever triggered the function. The second is an event handle. Matlab documentation suggests using gcbo() to get the handle to the object that triggered the function (see here) but that handle is also present in the first input.
If all of the data you need in your callback function are contained in the UI table, you do not need additional inputs and you can define the callback function using a function handles as shown in this example.
If you'd like to pass additional variables to the callback function you'll need to specify those inputs in a cell array as shown in this example.
So your callback definition will look like one of these two lines below.
uit = uitable(. . .,'DeleteFcn',@MyDeleteFcn); %Option 1
% or
uit = uitable(. . .,'DeleteFcn',{@MyDeleteFcn,var1,var2,etc}); %Option 2
The callback function itself should match the number of inputs provided above +2.
% If you chose option 1 above.
function data = MyDeleteFcn(hObject, event)
% If you chose option 2 above
function data = MyDeleteFcn(hObject, event, var1, var2, etc)
Callback function outputs (or the lack there of)
I noticed your callback function contains an output. Callback functions do not have outputs. They only respond to a triggering event do not send anything back.
"I wanted to capture the new data and rewrite it back into the .mat file"
There are two common ways to use callback functions.
1) everything you need done happens within that function.
2) that function does its work and then saves any "outputs" to the gui itself using guidata() so other GUI components have access to that data. However, there's no signal to announce when the callback function completes other than the destruction of the figure in this case. So you could use the destruction of the figure as a signal that the stored data is ready and you can use guidata() again to retreive the data.
  5 Kommentare
Justin Ruiz
Justin Ruiz am 9 Sep. 2019
Thank you all for your quick replies. I was off the weekend and didn't get to reply until today. I see why the callback works when not in GUI since it is called to the base workspace. I now just have to figure out how to call a variable from a subfuction into a function that is being called by the GUI. GUI button calls function1 which calls function2 (deletefcn) which gives an output back to function1. I now know the Deletefcn has no direct output within a GUI but I don't see why I can't pass a variable back to function1 using handles. I've looked through other posts but I don't see any regarding a uitable. I've tried
function MyDeleteFcn(uit,event)
handles.data = get(uit,'Data');
guidata(handles.data, handles);
end
but I can't seem to pull it out using data = guidata(handles.data). Does guidata only return variables to the GUI and not globally to function1?
Stephen23
Stephen23 am 10 Sep. 2019
Bearbeitet: Stephen23 am 10 Sep. 2019
"Does guidata only return variables to the GUI and not globally to function1?"
guidata does not "return" variables anywhere. It stores variables in a structure which is located in the figure that is the parent of the graphics object which was given as the first input argument (as its documentation clearly describes).
As long as you have the handle of any graphics object in your GUI, then you can use guidata to obtain that stored structure again. It has nothing to do with "globally" or functions.
" I can't seem to pull it out using data = guidata(handles.data)"
The guidata documentation states that the first input argument must be a handle to any graphics object in your GUI. What is its first input argument in your code?
You probably want something more like this:
function MyDeleteFcn(uit,event)
handles = guidata(uit); % get structure from figure
handles.data = get(uit,'Data');
guidata(uit, handles); % store structure in figure
end

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Migrate GUIDE Apps finden Sie in Help Center und File Exchange

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by