Matlab GUI:在 KeyPressFcn 调用之前等待值更新
Matlab GUI: waiting for value update before KeyPressFcn call
我正在用 Matlab 编写一个 GUI,除其他功能外,它应该允许您在 edit
-uicontrol
中编写文本,然后在按下时将该文本添加到列表中输入密钥。
我正在使用编辑框的 KeyPressFcn
方法来测试是否按下了 enter,我的问题是它没有更新 edit
[的 String
值 uicontrol
,所以添加到列表中的字符串实际上不是我刚刚输入的字符串,而是 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说的挺简洁的,我之前找的比较绕。
我正在用 Matlab 编写一个 GUI,除其他功能外,它应该允许您在 edit
-uicontrol
中编写文本,然后在按下时将该文本添加到列表中输入密钥。
我正在使用编辑框的 KeyPressFcn
方法来测试是否按下了 enter,我的问题是它没有更新 edit
[的 String
值 uicontrol
,所以添加到列表中的字符串实际上不是我刚刚输入的字符串,而是 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说的挺简洁的,我之前找的比较绕。