用户界面-MATLAB GUI:当在子函数中创建新对象时,如何更新句柄



我的MATLAB GUI有问题。

我没有使用GUIDE,所以我对GUI的所有内容都进行了自我编码。我有一个Main,它生成GUIDE的第一个面板。这个面板包含一个按钮,可以通过其相关的回调功能创建其他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,以获得handles的最新版本。如果回调对句柄结构进行了更改,请再次调用guidata,为其他回调存储这些更改。

最新更新