【问题标题】:Manage multiple callbacks管理多个回调
【发布时间】:2015-05-04 13:53:22
【问题描述】:

我已经制作了一个用户界面,其中包含许多在循环中创建的编辑文本框,现在我想将用户输入存储在一个带有回调的变量中。

例如考虑这段代码,

function p = myfun()
f = figure;
set(f,'Position',[200 350 250 150],'Color',[.4 .6 .4],'MenuBar','none',...
    'Visible','off');
bc = [.4 .6 .4];
uicontrol('Style','text','Position',[50 80 80 30],...
        'String','X','BackgroundColor',bc,'ForegroundColor','w');
uicontrol('Style','text','Position',[50 40 80 30],...
        'String','Y','BackgroundColor',bc,'ForegroundColor','w');
uicontrol('style','edit','Position', [120 80 80 30],...
    'BackgroundColor',bc,'ForegroundColor','w','Callback',{@My_Callback});
uicontrol('style','edit','Position', [120 40 80 30],...
    'BackgroundColor',bc,'ForegroundColor','w','Callback',{@My_Callback});
uicontrol('Style', 'pushbutton', 'String', 'Ok',...
    'Position', [100 5 60 30],'Callback', 'close'); 
movegui(f,'center')
set(f,'Visible','on')

function My_Callback(hObject,eventdata)
    p = str2double(get(hObject,'string'));
end
end

现在My_Callback 将被调用两次,但只有最后一个会存储在p 中。

但我希望它们像 p.xp.y 一样存储。

我想我应该使用Tag,它说:

Tag

string (GUIDE sets this property)

User-specified object label. The Tag property provides a means to identify graphics objects with a user-specified label. This is particularly useful when constructing interactive graphics programs that would otherwise need to define object handles as global variables or pass them as arguments between callback routines. You can define Tag as any string.

但我不知道如何(我有大约 16 个可编辑框),

感谢您的帮助。

【问题讨论】:

  • 您希望何时从编辑框中读取值,在输入后立即读取,还是在按下“确定”按钮后读取?
  • @MikhailGenkin,在按下ok 之后,因为用户可能会更改它们。谢谢

标签: matlab function user-interface


【解决方案1】:

如果我正确理解了您的问题,您可以使用uicontrolsUserData 属性在您输入编辑框时存储它的内容,这样可以很容易地在您的GUI 中的任何位置恢复它们或别处。

此外,为了方便您可以在创建 uicontrols 期间为其分配名称,因此当您需要获取它们的一个/多个属性时,您可以使用其名称而不是 hObject 参数来调用句柄。

例如,假设您将框命名为 X 数据 x1,然后您可以像这样创建并将其存储在 GUI 的句柄结构中:

handles.x1 = uicontrol(...)

所以当你需要获取一个属性时,你可以使用

get(handles.x1,'Some Property');

所以回到您的问题,您可以使用此语法设置My_Callback 内所有框的UserData 属性。之后,您可以在任何您想要的回调中恢复它们。当然,一种简单的方法是获取编辑框的String 属性而不是它们的UserData,但使用后者,您可以存储任何您想要的可能派上用场的东西。

在以下 GUI 中,我修改了您的 GUI,以更改名为 DisplayData 的函数的“确定”按钮的回调,该函数从每个编辑框中获取 UserData 并显示它。

function p = myfun()
clear
clc

f = figure;
set(f,'Position',[200 350 250 150],'Color',[.4 .6 .4],'MenuBar','none',...
    'Visible','off');
bc = [.4 .6 .4];
%//===============
uicontrol('Style','text','Position',[50 80 80 30],...
    'String','X','BackgroundColor',bc,'ForegroundColor','w');

uicontrol('Style','text','Position',[50 40 80 30],...
    'String','Y','BackgroundColor',bc,'ForegroundColor','w');
%//===============

handles.x1 = uicontrol('style','edit's,'Position', [120 80 80 30],...
    'BackgroundColor',bc,'ForegroundColor','w','Callback',{@My_Callback});

handles.y1 = uicontrol('style','edit','Position', [120 40 80 30],...
    'BackgroundColor',bc,'ForegroundColor','w','Callback',{@My_Callback});
%//===============
uicontrol('Style', 'pushbutton', 'String', 'Ok',...
    'Position', [100 5 60 30],'Callback', @(s,e) DisplayData);

movegui(f,'center')
set(f,'Visible','on')

guidata(f,handles); %// Updata guidata

    function My_Callback(hObject,eventdata)

        p = str2double(get(hObject,'string'));

        %// Assign the content of the box to its "UserData" property
        set(hObject,'UserData',p)
        guidata(f,handles)
    end

    function DisplayData(~,~)


        %// You could do it for all the boxes in your GUI.
       x1Data = get(handles.x1,'UserData');
       y1Data = get(handles.y1,'UserData');

       fprintf('The number in box 1 is %0.2f and the number in box 2 is %0.2f\n',x1Data,y1Data);

       guidata(f,handles)
    end
end

样本输出:

按下“确定”按钮后,这个字符串会显示在命令行窗口中:

The number in box 1 is 2.00 and the number in box 2 is 4.00

希望有帮助!

【讨论】:

  • 太棒了,很高兴能提供帮助!
  • DisplayData 的输入是什么?
  • 实际上它们并不是绝对必要的,这是我的习惯,但我前段时间在某处读到,在某些情况下,匿名函数至少需要 2 个输入参数,以避免错误的输入/输出#论据(我希望我还有来源)所以总是这样称呼他们成为一种习惯。
  • 好吧,再次感谢。
【解决方案2】:

正如您在 cmets 中提到的,您希望在按下“确定”按钮后从编辑框中读取您的值。为此,您应该将回调函数分配给“确定”按钮,而不是编辑框:

uicontrol('Style', 'pushbutton', 'String', 'Ok',...
'Position', [100 5 60 30],'Callback', {@My_Callback});

在您的回调函数中,您应该从所有编辑框中读取值。

我建议您在定义编辑框时使用句柄(最好将其用于所有对象):

 e1=uicontrol('style','edit','Position', [120 80 80 30],...
'BackgroundColor',bc,'ForegroundColor','w');
e2=uicontrol('style','edit','Position', [120 40 80 30],...
'BackgroundColor',bc,'ForegroundColor','w');

现在,为了读取值,您只需使用相应编辑框的句柄即可。

function My_Callback(hObject,eventdata)
    p1 = str2double(get(e1,'string'));
    p2 = str2double(get(e2,'string'));
end

注意:此句柄 (e1,e2) 在您的代码中将具有青色,这意味着它们是“全局”变量,即用于主代码和回调函数。

如果您不想使用全局句柄,可以将它们传递给回调函数。所以你的回调函数会有更多的参数。

uicontrol('Style', 'pushbutton', 'String', 'Ok',...
'Position', [100 5 60 30],'Callback', {@My_Callback(e1,e2)});

function My_Callback(hObject,eventdata,e1,e2)
    p1 = str2double(get(e1,'string'));
    p2 = str2double(get(e2,'string'));
end

【讨论】:

  • 我刚刚编辑了我的答案:你不应该对编辑框使用回调函数。
  • 谢谢,为按钮定义回调的要点。我在循环中定义了这些框,让我看看我是否可以处理。
猜你喜欢
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多