MATLAB GUI:如何在子函数中创建新对象时更新句柄?
MATLAB GUI: how to update handles when new objects are created in a subfunction?
我的 MATLAB GUI 有问题。
我没有使用 GUIDE,所以我自己为我的 GUI 编写所有代码。我有一个 Main,它生成 GUIDE 的第一个面板。该面板包含一个按钮,可以通过其相关的回调函数创建其他 2 个面板。在其他 2 个面板中,可以执行调用其他回调函数的其他操作。这些操作之一是创建 2 个新的静态文本和 2 个新的可编辑文本。我在更新与那些可编辑文本相关的句柄时遇到问题。更准确地说,一旦编辑文本并再次调用最后 2 个面板的回调函数,我就无法检索它们的字符串值。
附上GUI所有回调函数的代码:
%% server_selected callback function
function server_selected(hObject, eventdata, handles)
%UNTITLED8 Summary of this function goes here
% Detailed explanation goes here
% Get server version and run LaunchCDbQuery
servers = get(handles.server_popup, 'String');
serverVersion = servers{get(handles.server_popup, 'Value')};
[Day] = LaunchCDbQuery(serverVersion);
assignin('base', 'Day', Day)
% Update current outing on GUI
set(handles.outing_text, 'String', strcat(Day.date, Day.DocumentKey))
% Tool description
% Create panel for the tool description
handles.description_panel = uipanel('Title', 'Tool description',...
'units', 'normalized',...
'position', [0.675, 0.025, 0.3, 0.9]);
% Create items inside the panel for the tool description
% Function heading
handles.funheading_text = uicontrol('Parent', handles.description_panel,...
'Style', 'text',...
'units', 'normalized',...
'position', [0, 0.7, 1, 0.2],...
'String', 'Please choose a tool and click description to obtain the tool''s heading and description.',...
'HorizontalAlignment', 'left');
% Function description
handles.description_text = uicontrol('Parent', handles.description_panel,...
'Style', 'text',...
'units', 'normalized',...
'position', [0, 0.05, 1, 0.6],...
'HorizontalAlignment', 'left');
% Tool selection
% Create panel for the tool selection
handles.tool_panel = uipanel('Title', 'Tool selection',...
'units', 'normalized',...
'position', [0.35 0.025 0.3 0.9]);
% Create items inside the panel for the tool selection
% Text
handles.tool_text = uicontrol('Parent', handles.tool_panel,...
'Style', 'text',...
'units', 'normalized',...
'position', [0 0.7 1 0.2],...
'String', 'Please choose a tool to perform a piece of analysis.',...
'HorizontalAlignment', 'left');
% Popup
handles.tool_popup = uicontrol('Parent', handles.tool_panel,...
'Style', 'popup',...
'units', 'normalized',...
'position', [0.2 0.25 0.6 0.4],...
'String', {'plotmaptg'; 'TestReview'});
% Input variables panel
handles.varin_panel = uipanel('Parent', handles.tool_panel,...
'Title', 'Type input variables',...
'units', 'normalized',...
'position', [0, 0, 1, 0.3]);
% Description push
handles.tool_push_description = uicontrol('Parent', handles.tool_panel,...
'Style', 'pushbutton',...
'units', 'normalized',...
'position', [0.05 0.4 0.4 0.1],...
'String', 'Description',...
'callback', {@tool_description, handles});
% Ok push
handles.tool_push_ok = uicontrol('Parent', handles.tool_panel,...
'Style', 'pushbutton',...
'units', 'normalized',...
'position', [0.51 0.4 0.4 0.1],...
'String', 'Ok',...
'callback', {@tool_selected, handles, Day});
% Update guidata
guidata(hObject, handles)
end
%% tool_description callback function
function tool_description(hObject, eventdata, handles)
%UNTITLED2 Summary of this function goes here
% Detailed explanation goes here
% Call handles function
handles = tool_description_handles(handles);
% Update guidata
guidata(hObject, handles)
end
function newHandles = tool_description_handles(handles)
%UNTITLED Summary of this function goes here
% Detailed explanation goes here
% Get tool name
tools = get(handles.tool_popup, 'String');
tool_selected = tools{get(handles.tool_popup, 'Value')};
% Open tool .m file
fid = fopen(strcat(tool_selected, '.m'), 'r');
% Read .m file to find function description and save it
line = fgets(fid);
heading = line;
while isempty(regexp(line, '%', 'ONCE'))
line = fgets(fid);
end
description = [];
while ~isempty(regexp(line, '%', 'ONCE'))
description = strcat(description, line(regexp(line, '%', 'ONCE'):end));
line = fgets(fid);
end
description(regexp(description, '%')) = [];
fclose(fid);
% Set descritption found to the description handle
set(handles.funheading_text, 'String', heading);
set(handles.description_text, 'String', description);
% Find the input variables needed to run the tool
global inputs varout
[varin, varout] = get_arg_names(strcat(pwd, '\Tools\', tool_selected, '.m'));
inputs = cell(1, length(varin{1,1}));
for i = 1:length(varin{1,1})
% Input variable text
handles.varin_text(i) = uicontrol('Parent', handles.varin_panel,...
'Style', 'text',...
'units', 'normalized',...
'position', [0, 1-i*(1/length(varin{1,1})), 0.45, 1/length(varin{1,1})],...
'String', varin{1,1}{i,1},...
'HorizontalAlignment', 'left');
% Input variables editable text
handles.varin_edit(i) = uicontrol('Parent', handles.varin_panel,...
'Style', 'edit',...
'units', 'normalized',...
'position', [0.55, 1-i*(1/length(varin{1,1})), 1, 1/length(varin{1,1})],...
'HorizontalAlignment', 'left',...
'callback', {@varin_callback, handles});
end
% Save handles
newHandles = handles;
end
function varin_callback(hObject, eventdata, handles)
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Save in the main workspace the input variables
global inputs
for i = 1:length(inputs)
if isempty(inputs{1,i})
inputs{1,i} = get(hObject,'String');
break
end
end
end
%% tool_selected callback function
function tool_selected(hObject, eventdata, handles, Day)
%UNTITLED Summary of this function goes here
% Detailed explanation goes here
% Get tool name
tools = get(handles.tool_popup, 'String');
tool = tools{get(handles.tool_popup, 'Value')};
% fh = str2func(tool);
% Get tool inputs and outputs
global inputs varout
% Run the tool
if ~isempty(varout)
expression = strcat('out = ', tool, '(');
else
expression = strcat(tool, '(');
end
for i = 1:length(inputs)
if ~isempty(inputs{1,i})
expression = strcat(expression, inputs{1,i}, ',');
else
break
end
end
expression(end) = ')';
eval(expression)
% Update guidata
guidata(hObject, handles)
end
我试过在每个函数的末尾使用 guidata(hObject, handles)
但没有成功。现在我正在使用全局变量来避免这个问题,但我真的很想在句柄被修改时更新它们。
向回调函数提供输入变量时,调用回调时传递的变量是定义回调时存在的变量。 MATLAB 不知道在您修改 guidata
.
时更新这些输入
您可以通过以下示例看到这一点:
function testcode
h.mf = figure('Menubar', 'none', 'NumberTitle', 'off', 'ToolBar', 'none');
h.lb = uicontrol('Parent', h.mf, 'Style', 'Listbox', ...
'Units', 'Normalized', 'Position', [0.1 0.5 0.4 0.4] ...
);
h.b1 = uicontrol('Parent', h.mf, 'Style', 'pushbutton', ...
'Units', 'Normalized', 'Position', [0.1 0.1 0.4 0.3], ...
'String', 'Pass handles','Callback', {@button1push, h});
h.b2 = uicontrol('Parent', h.mf, 'Style', 'pushbutton', ...
'Units', 'Normalized', 'Position', [0.5 0.1 0.4 0.3], ...
'String', 'Use GUIdata', 'Callback', @button2push);
guidata(h.mf, h);
makepanel(h.mf);
end
function makepanel(mf)
h = guidata(mf);
h.panel = uipanel('Parent', h.mf, 'Title', 'A Panel', ...
'Units', 'Normalized', 'Position', [0.5 0.5 0.4 0.4] ...
);
guidata(h.mf, h);
end
function button1push(~, ~, h)
h.lb.String = fieldnames(h);
end
function button2push(hObj, ~)
h = guidata(hObj);
h.lb.String = fieldnames(h);
end
按每个按钮并查看列表框中的输出。您可以看到,当您点击按钮 1 时,在 makepanel
中对 h
所做的更改不会显示。
与其将 handles
作为回调输入传递(如上面的按钮 1),不如在函数开头调用 guidata
并输出,以获得 [=14= 的最新版本].如果您的回调对句柄结构进行了更改,请再次调用 guidata
以存储这些更改以供其他回调使用。
我的 MATLAB GUI 有问题。
我没有使用 GUIDE,所以我自己为我的 GUI 编写所有代码。我有一个 Main,它生成 GUIDE 的第一个面板。该面板包含一个按钮,可以通过其相关的回调函数创建其他 2 个面板。在其他 2 个面板中,可以执行调用其他回调函数的其他操作。这些操作之一是创建 2 个新的静态文本和 2 个新的可编辑文本。我在更新与那些可编辑文本相关的句柄时遇到问题。更准确地说,一旦编辑文本并再次调用最后 2 个面板的回调函数,我就无法检索它们的字符串值。
附上GUI所有回调函数的代码:
%% server_selected callback function
function server_selected(hObject, eventdata, handles)
%UNTITLED8 Summary of this function goes here
% Detailed explanation goes here
% Get server version and run LaunchCDbQuery
servers = get(handles.server_popup, 'String');
serverVersion = servers{get(handles.server_popup, 'Value')};
[Day] = LaunchCDbQuery(serverVersion);
assignin('base', 'Day', Day)
% Update current outing on GUI
set(handles.outing_text, 'String', strcat(Day.date, Day.DocumentKey))
% Tool description
% Create panel for the tool description
handles.description_panel = uipanel('Title', 'Tool description',...
'units', 'normalized',...
'position', [0.675, 0.025, 0.3, 0.9]);
% Create items inside the panel for the tool description
% Function heading
handles.funheading_text = uicontrol('Parent', handles.description_panel,...
'Style', 'text',...
'units', 'normalized',...
'position', [0, 0.7, 1, 0.2],...
'String', 'Please choose a tool and click description to obtain the tool''s heading and description.',...
'HorizontalAlignment', 'left');
% Function description
handles.description_text = uicontrol('Parent', handles.description_panel,...
'Style', 'text',...
'units', 'normalized',...
'position', [0, 0.05, 1, 0.6],...
'HorizontalAlignment', 'left');
% Tool selection
% Create panel for the tool selection
handles.tool_panel = uipanel('Title', 'Tool selection',...
'units', 'normalized',...
'position', [0.35 0.025 0.3 0.9]);
% Create items inside the panel for the tool selection
% Text
handles.tool_text = uicontrol('Parent', handles.tool_panel,...
'Style', 'text',...
'units', 'normalized',...
'position', [0 0.7 1 0.2],...
'String', 'Please choose a tool to perform a piece of analysis.',...
'HorizontalAlignment', 'left');
% Popup
handles.tool_popup = uicontrol('Parent', handles.tool_panel,...
'Style', 'popup',...
'units', 'normalized',...
'position', [0.2 0.25 0.6 0.4],...
'String', {'plotmaptg'; 'TestReview'});
% Input variables panel
handles.varin_panel = uipanel('Parent', handles.tool_panel,...
'Title', 'Type input variables',...
'units', 'normalized',...
'position', [0, 0, 1, 0.3]);
% Description push
handles.tool_push_description = uicontrol('Parent', handles.tool_panel,...
'Style', 'pushbutton',...
'units', 'normalized',...
'position', [0.05 0.4 0.4 0.1],...
'String', 'Description',...
'callback', {@tool_description, handles});
% Ok push
handles.tool_push_ok = uicontrol('Parent', handles.tool_panel,...
'Style', 'pushbutton',...
'units', 'normalized',...
'position', [0.51 0.4 0.4 0.1],...
'String', 'Ok',...
'callback', {@tool_selected, handles, Day});
% Update guidata
guidata(hObject, handles)
end
%% tool_description callback function
function tool_description(hObject, eventdata, handles)
%UNTITLED2 Summary of this function goes here
% Detailed explanation goes here
% Call handles function
handles = tool_description_handles(handles);
% Update guidata
guidata(hObject, handles)
end
function newHandles = tool_description_handles(handles)
%UNTITLED Summary of this function goes here
% Detailed explanation goes here
% Get tool name
tools = get(handles.tool_popup, 'String');
tool_selected = tools{get(handles.tool_popup, 'Value')};
% Open tool .m file
fid = fopen(strcat(tool_selected, '.m'), 'r');
% Read .m file to find function description and save it
line = fgets(fid);
heading = line;
while isempty(regexp(line, '%', 'ONCE'))
line = fgets(fid);
end
description = [];
while ~isempty(regexp(line, '%', 'ONCE'))
description = strcat(description, line(regexp(line, '%', 'ONCE'):end));
line = fgets(fid);
end
description(regexp(description, '%')) = [];
fclose(fid);
% Set descritption found to the description handle
set(handles.funheading_text, 'String', heading);
set(handles.description_text, 'String', description);
% Find the input variables needed to run the tool
global inputs varout
[varin, varout] = get_arg_names(strcat(pwd, '\Tools\', tool_selected, '.m'));
inputs = cell(1, length(varin{1,1}));
for i = 1:length(varin{1,1})
% Input variable text
handles.varin_text(i) = uicontrol('Parent', handles.varin_panel,...
'Style', 'text',...
'units', 'normalized',...
'position', [0, 1-i*(1/length(varin{1,1})), 0.45, 1/length(varin{1,1})],...
'String', varin{1,1}{i,1},...
'HorizontalAlignment', 'left');
% Input variables editable text
handles.varin_edit(i) = uicontrol('Parent', handles.varin_panel,...
'Style', 'edit',...
'units', 'normalized',...
'position', [0.55, 1-i*(1/length(varin{1,1})), 1, 1/length(varin{1,1})],...
'HorizontalAlignment', 'left',...
'callback', {@varin_callback, handles});
end
% Save handles
newHandles = handles;
end
function varin_callback(hObject, eventdata, handles)
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Save in the main workspace the input variables
global inputs
for i = 1:length(inputs)
if isempty(inputs{1,i})
inputs{1,i} = get(hObject,'String');
break
end
end
end
%% tool_selected callback function
function tool_selected(hObject, eventdata, handles, Day)
%UNTITLED Summary of this function goes here
% Detailed explanation goes here
% Get tool name
tools = get(handles.tool_popup, 'String');
tool = tools{get(handles.tool_popup, 'Value')};
% fh = str2func(tool);
% Get tool inputs and outputs
global inputs varout
% Run the tool
if ~isempty(varout)
expression = strcat('out = ', tool, '(');
else
expression = strcat(tool, '(');
end
for i = 1:length(inputs)
if ~isempty(inputs{1,i})
expression = strcat(expression, inputs{1,i}, ',');
else
break
end
end
expression(end) = ')';
eval(expression)
% Update guidata
guidata(hObject, handles)
end
我试过在每个函数的末尾使用 guidata(hObject, handles)
但没有成功。现在我正在使用全局变量来避免这个问题,但我真的很想在句柄被修改时更新它们。
向回调函数提供输入变量时,调用回调时传递的变量是定义回调时存在的变量。 MATLAB 不知道在您修改 guidata
.
您可以通过以下示例看到这一点:
function testcode
h.mf = figure('Menubar', 'none', 'NumberTitle', 'off', 'ToolBar', 'none');
h.lb = uicontrol('Parent', h.mf, 'Style', 'Listbox', ...
'Units', 'Normalized', 'Position', [0.1 0.5 0.4 0.4] ...
);
h.b1 = uicontrol('Parent', h.mf, 'Style', 'pushbutton', ...
'Units', 'Normalized', 'Position', [0.1 0.1 0.4 0.3], ...
'String', 'Pass handles','Callback', {@button1push, h});
h.b2 = uicontrol('Parent', h.mf, 'Style', 'pushbutton', ...
'Units', 'Normalized', 'Position', [0.5 0.1 0.4 0.3], ...
'String', 'Use GUIdata', 'Callback', @button2push);
guidata(h.mf, h);
makepanel(h.mf);
end
function makepanel(mf)
h = guidata(mf);
h.panel = uipanel('Parent', h.mf, 'Title', 'A Panel', ...
'Units', 'Normalized', 'Position', [0.5 0.5 0.4 0.4] ...
);
guidata(h.mf, h);
end
function button1push(~, ~, h)
h.lb.String = fieldnames(h);
end
function button2push(hObj, ~)
h = guidata(hObj);
h.lb.String = fieldnames(h);
end
按每个按钮并查看列表框中的输出。您可以看到,当您点击按钮 1 时,在 makepanel
中对 h
所做的更改不会显示。
与其将 handles
作为回调输入传递(如上面的按钮 1),不如在函数开头调用 guidata
并输出,以获得 [=14= 的最新版本].如果您的回调对句柄结构进行了更改,请再次调用 guidata
以存储这些更改以供其他回调使用。