1

我正在使用编程方法在 Matlab 中构建 GUI(所以没有 GUIDE 和没有 AppDesigner)。我的 GUI 包含一个只应接受某些输入的编辑字段。因此,我使用了一个回调来清理输入,然后相应地更新编辑字段的 String 属性。但是,当我更新 String 属性时,插入符号(“光标)”卡住了:它停止闪烁,尽管您仍然可以左右移动它,但它的幻影副本仍将绘制在输入的左边缘。

最小工作示例,使用随机数:

figure;
edit_cb = @(h, e) set(h, 'String', num2str(rand(1)));
uicontrol('Style', 'edit', 'String', '0', 'Callback', edit_cb);

结果(在 Win7 上,使用 Matlab2016a 或 Matlab2014b):

在此处输入图像描述

如何在插入符号卡住的情况下更新字段内的字符串?

4

2 回答 2

0

我找到了一个解决方法:在回调中,您可以先将焦点切换到虚拟元素,然后更新感兴趣的元素,最后将焦点切换回感兴趣的元素。该解决方案的缺点:文本全部突出显示。此外,该解决方案有些脆弱:出于非显而易见的原因,必须在单独的set调用中将虚拟元素的可见性设置为“关闭”。

由于新的回调跨越了几行,它不能再被描述为一个匿名函数。这使得最小示例稍长:

function caret_stuck_hack()

figure
hedit = uicontrol('Style', 'edit', 'String', '0', 'Callback', @edit_cb);
hdummy = uicontrol('Style', 'edit', 'String', 'dummy', ...
    'Position', [0, 0, 1, 1]); % Position: HAS to be non-overlapping with other edit field
hdummy.Visible = 'off'; % Don't merge with upper line! HAS to be called seperately! 

function edit_cb(h, e)
    uicontrol(hdummy);
    h.String = num2str(rand(1));
    uicontrol(h);
    drawnow;
end

end

结果:

在此处输入图像描述

附录

您可以通过操作底层 Java Swing 对象来更改插入符号的位置。使用Yair Altman 的优秀 findjobj功能,代码变为:

function caret_stuck_hack()

figure
hedit = uicontrol('Style', 'edit', 'String', '0', 'Callback', @edit_cb);
hdummy = uicontrol('Style', 'edit', 'String', 'dummy', ...
    'Position', [0, 0, 1, 1]); % Position: HAS to be non-overlapping with other edit field
hdummy.Visible = 'off'; % Don't merge with upper line! HAS to be called seperately! 

jhedit = findjobj(hedit, 'nomenu');

function edit_cb(h, e)
    caret_pos = get(jhedit, 'CaretPosition');
    uicontrol(hdummy);
    h.String = num2str(rand(1));
    uicontrol(h);
    drawnow;
    set(jhedit, 'CaretPosition', caret_pos)
end

end

您可以(也许应该)添加额外的代码来检查插入符索引在字符串长度更改时是否非法。但是对于这个最小的例子,结果看起来已经很不错了:

在此处输入图像描述

于 2016-07-13T12:50:32.480 回答
0

尝试使用set更新值,然后drawnow强制刷新 uicontrol。

set(h, 'String', StrValue);
drawnow;

h你的 uicontrol 的句柄在哪里

于 2016-07-13T12:16:27.980 回答