我正在使用the programmatic approach在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):
如果插入的插入符号如何更新字段内的字符串?
答案 0 :(得分:0)
尝试使用set
更新值,然后使用drawnow
强制刷新uicontrol。
set(h, 'String', StrValue);
drawnow;
其中h
是您的uicontrol的句柄
答案 1 :(得分: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's excellent 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
您可以(也许应该)添加其他代码,以便在字符串长度发生变化时检查插入符号索引是否非法。但是对于这个最小的例子,结果已经看起来很不错了: