Matlab GUI:在KeyPressFcn调用之前等待值更新

时间:2015-01-07 10:53:35

标签: matlab user-interface

我在Matlab中编写一个GUI,其中包括其他功能应允许您在edit - uicontrol中编写文本,然后在按Enter键时将该文本添加到列表中

我正在使用编辑框的KeyPressFcn方法来测试是否按下了输入,我的问题是它没有更新String {{1}的edit值添加到列表中的字符串实际上并不是我刚输入的字符串,而是uicontrol中字符串的先前版本。

现在我已经搜索了这个问题的解决方案并找到了solution,但我更喜欢Matlab中严格包含的解决方案 - 这不是指java。

这可能吗?如果是,怎么样?

最小的工作示例:

edit

编辑:我正在运行Matlab R2014a。

2 个答案:

答案 0 :(得分:1)

您的解决方案的问题是每次输入单个字符时都会调用按键功能。改为使用Callback

function [fig] = tmpGUI()
    fig = figure('MenuBar','none');
    handles.fig = fig;
    handles.edit = uicontrol(fig,'Style','edit','Units','Normalized','Position',[.05,.75,.8,.2],'Backgroundcolor','white','String','', 'Callback',@edit_KeyPressFcn);
    handles.list = uicontrol(fig,'Style','listbox','Units','Normalized','Position',[.05,.05,.9,.65],'Backgroundcolor','white','String','First element in list');

    guidata(fig,handles);
    uicontrol(handles.edit);
end

function edit_KeyPressFcn(hObject, eventdata)

    handles = guidata(hObject);
    str = get(handles.edit,'String');

    % ignore empty strings
    if isempty(str)
        return;
    end

    liste = cellstr(get(handles.list,'String'));
    liste{end+1} = str;
    set(handles.list,'String',char(liste),'Value',numel(liste));

end

答案 1 :(得分:1)

callback时会触发edit uicontrol的enter属性,因此使用此回调代替KeyPressFcn会更容易。

当您输入回调时,请检查按下的最后一个字符是enter。如果是,请更新您的列表,如果不是什么也不做,继续。

这个例子好像你问的那样。如果有其他条件需要检查,请告诉我。

function [fig] = tmpGUI()
    fig = figure('MenuBar','none');
    handles.fig = fig;
    handles.edit = uicontrol(fig,'Style','edit','Units','Normalized','Position',[.05,.75,.9,.2],'Backgroundcolor','white','String','','Callback',@edit_callback);
    handles.list = uicontrol(fig,'Style','listbox','Units','Normalized','Position',[.05,.05,.9,.65],'Backgroundcolor','white','String','First element in list');
    guidata(fig,handles);
    uicontrol(handles.edit);
end

function edit_callback(hObject, evt)
    handles = guidata(hObject);
    %// just check if the last key pressed was "enter"
    %// if yes, update the list 
    if double(get(gcf,'currentcharacter'))==13
        str = get(handles.edit,'String');
        liste = cellstr(get(handles.list,'String'));
        liste{end+1} = str;
        set(handles.list,'String',char(liste),'Value',numel(liste));
    end
    %// if not, the callback has been trigerred by a click somewhere else
    %// this is not a validation condition to update the list so we just
    %// do ... nothing
end

编辑:要添加更多信息,Matlab编辑uicontrol在验证之前不会在内部更新。编辑中的值仅通过(i)按下enter键或(ii)txtbox失去焦点(用户单击其他位置)进行验证。

在您最初的情况下,您正在拦截enter密钥并执行代码,但由于您截获了enter密钥,因此文本框尚未验证,并且在其内部存储器中仍然存在旧值,所以你的拦截代码捕获旧值。记住我回答的与这些文本框有关的旧问题,没有Matlab方法强制文本框以编程方式验证其内容而不使用一些java技巧。

所以在你的情况下(你想对enter键作出反应),由于回调机制,它可以在纯Matlab中实现。如果你想在响应任何其他键时执行一些代码,那么你必须以编程方式强制执行文本框验证,这只能通过调用java方法来实现(实际上你在原始帖子中提到的链接)非常整洁,我之前发现的方式非常复杂。)