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

Matlab GUI: waiting for value update before KeyPressFcn call

我正在用 Matlab 编写一个 GUI,除其他功能外,它应该允许您在 edit-uicontrol 中编写文本,然后在按下时将该文本添加到列表中输入密钥。

我正在使用编辑框的 KeyPressFcn 方法来测试是否按下了 enter,我的问题是它没有更新 edit [的 Stringuicontrol,所以添加到列表中的字符串实际上不是我刚刚输入的字符串,而是 edit.

中字符串的前一个化身

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

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

一个最小的工作示例:

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','','KeyPressFcn',@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);
    switch eventdata.Key
        case 'return'
            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
end

编辑:我正在运行 Matlab R2014a。

您的解决方案的问题在于每次输入单个字符时都会调用按键功能。使用 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

edit uicontrol 的 callback 属性 会在你按下 enter 时被触发,所以使用这个回调比 [=] 更容易14=].

当你进入回调时,检查最后按下的字符是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 方法(实际上是link你原来的post说的挺简洁的,我之前找的比较绕。