2016-08-05 5 views
1

내 MATLAB GUI에 문제가 있습니다.MATLAB GUI : 새 객체가 하위 함수에서 만들어 질 때 핸들을 업데이트하는 방법은 무엇입니까?

GUIDE를 사용하지 않으므로 GUI에 대해 모든 것을 자체 코딩하고 있습니다. GUIDE의 첫 번째 패널을 생성하는 Main이 있습니다. 이 패널에는 관련 콜백 기능을 통해 다른 2 개의 패널을 만들 수있는 버튼이 있습니다. 다른 두 패널에서는 다른 콜백 함수를 호출하는 다른 작업을 수행 할 수 있습니다. 이 작업 중 하나는 2 개의 새로운 정적 텍스트와 2 개의 새로운 편집 가능한 텍스트를 만드는 것입니다. 편집 가능한 텍스트와 관련된 핸들을 업데이트하는 데 문제가 있습니다. 정확히 말하면 텍스트가 편집되고 마지막 두 패널의 콜백 함수가 다시 호출되면 문자열의 값을 검색 할 수 없습니다. 나는 각 기능의 끝에 guidata(hObject, handles)를 사용하여 시도했지만 그것이 작동하지 않았다

%% 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 

: 첨부

는 GUI의 모든 콜백 함수는 코드입니다. 지금은 문제를 피하기 위해 전역 변수를 사용하고 있지만 수정 된 핸들을 업데이트하고 싶습니다.

+2

또한'handles' 구조체를 얻기 위해 콜백의 시작 부분에서'guidata'를 사용해야합니다. 각 콜백에'handles'을 건네 주면 콜백을 정의 할 때 존재했던'handles' 만 전달할 것입니다. – excaza

+0

excaza가 말했듯이, 만약 당신이'guidata'를 사용한다면, 필요한 각 콜백의 시작 부분에서'handles = guidata (hobj)'에 의해'handles' 구조체를 얻어야 만합니다. 그렇게하면 항상 "신선한"핸들을 검색 할 수 있습니다. 이렇게하면 콜백의 입력 매개 변수 목록에서 핸들을 완전히 제거 할 수 있습니다. – Hoki

+0

이제 귀하의 의견에 대해 분명히 말씀해 주셔서 감사합니다. – Francesco

답변

0

입력 변수를 콜백 함수에 제공 할 때 콜백을 호출 할 때 전달되는 변수는 콜백이 정의 될 때 존재하는 변수입니다. guidata을 수정할 때 MATLAB은 이러한 입력을 업데이트하지 않습니다.

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 

푸시 각 버튼 및 목록 상자의 출력에서 ​​볼 :

다음 예제와이를 볼 수 있습니다. 당신이 오히려 콜백 입력으로 handles을 전달하는 대신 버튼 1.

를 쳤을 때 당신은 makepanel에서 만든 h에 변경 사항이 표시되지 않는 것을 알 수 있습니다, 함수의 시작 부분에 출력 guidata 전화 (위의 버튼 1 등) handles의 최신 버전을 구하십시오. 콜백이 핸들 구조를 변경하면 guidata을 다시 호출하여 이러한 변경 사항을 다른 콜백에 저장하십시오.

+0

이제는 작동하고 나는 함수의 입력과 guidata로 핸들의 사용상의 차이를 이해했습니다. 감사! – Francesco