2016-08-05 3 views
1

私のMATLAB GUIに問題があります。MATLAB GUI:新しいオブジェクトがサブ関数内に作成されたときにハンドルを更新する方法は?

私はGUIDEを使用していないので、自分のGUIのためにすべてを自己コーディングしています。私はGUIDEの最初のパネルを生成するMainを持っています。このパネルには、関連するコールバック機能によって他の2つのパネルを作成できるボタンが含まれています。他の2つのパネルでは、他のコールバック関数を呼び出す他の操作を行うことができます。これらの操作の1つは、2つの新しい静的テキストと2つの新しい編集可能テキストを作成することです。編集可能なテキストに関連するハンドルを更新する際に問題があります。より正確には、テキストが編集され、最後の2つのパネルのコールバック関数が再度呼び出されると、その文字列の値を取得できません。

%% 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)を使用して試してみましたが、それはうまくいかなかった:添付

は、GUIのすべてのコールバック関数があるコードです。今は問題を回避するためにグローバル変数を使用していますが、ハンドルが変更されたときにハンドルを更新するのが本当に好きです。

+2

また、 'handles'構造体を取得するためにコールバックの先頭に' guidata'を使用する必要があります。各コールバックに 'handles'を渡すことは、あなたがコールバックを定義した時に存在していた' handles'だけを渡すことになります。 – excaza

+0

excazaが言ったように、 'guidata'を使うと、それを必要とする各コールバックの始めに' handles = guidata(hobj) 'によって' handles'構造体を取得する必要があります。そうすることで、常に "新鮮な" 'handles'を取得することができます。そうすれば、コールバックの入力パラメータのリストから' 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 

押しに各ボタンをし、リストボックスでの出力を見て:

次の例でこれを見ることができます。あなたはボタン1

ではなく(上記ボタン1など)のコールバックの入力としてhandlesを渡すを打ったときmakepanelで行われたhへの変更が示されていない、あなたの関数の先頭で出力してguidataを呼び出すことがわかりますhandlesの最新バージョンを入手してください。コールバックによってハンドル構造が変更された場合は、guidataに再度コールして、これらの変更を他のコールバックに保存します。

+0

これはうまくいきました。私は、関数とguidataの入力としてハンドルの使い方の違いを理解しました。ありがとう! – Francesco

関連する問題