一些背景
我使用 GUIDE 构建的图形和在运行时添加的程序放置的复选框的组合创建了一个 GUI。 复选框位于矩阵中,其中行数和列数在运行时确定。 为了跟踪每个复选框,我使用标记约定,如 cb_r1_c1
或 cb_r7_c10
来指示矩阵中的位置。
我创建了一个函数foo_cb_callback()
,用于检查传递给它的 hObject 信息,以确定刚刚单击的复选框的标签。 使用此信息(复选框的行和列(,此函数知道下一步该做什么。 我发现这是一种更干净、更安全的方式来处理未知数量的复选框的回调。 到目前为止,这种策略效果很好。只有一个问题。
问题所在
我在更改程序添加的复选框的回调属性以正确调用我的foo_cb_callback()
函数时遇到问题。
当您使用 get(objhandles.cb_r1_c1,'callback')
检查具有现有回调的现有复选框时
返回的变量属于类"function_handle",并将文本字符串打印到屏幕上
@(hObject,eventdata)testfuig('checkbox1_Callback',hObject,eventdata,guidata(hObject))
我想将其更改为
@(hObject,eventdata)testfuig('foo_cb_callback',hObject,eventdata,guidata(hObject))
我首先尝试了什么
我的第一次尝试是这样的。
callbackstr = '@(hObject,eventdata)testfuig(''foo_cb_callback'',hObject,eventdata,guidata(hObject))';
set(objhandles.cb_r1_c1,'callback',callbackstr);
但这不起作用,因为它只是一个字符串,而不是一个function_handle分类的对象。 似乎应该有某种方法可以获取字符串或单元格数组并将其转换为function_handle类。 这将是最理想的情况,因为我可以轻松控制任何 uielement 的回调。
我接下来尝试了什么
由于我已经使用 'uicontrol((' 函数构造复选框,因此我尝试在创建时添加回调。
tagstr = 'cb_r1_c1';
uicontrol(objhandles.mainfig, 'Style','checkbox','Tag',tagstr,'callback', 'foo_cb_callback(''hObject''));
这创建了复选框,并且确实在回调属性中foo_cb_callback(hObject)
,但是当单击该复选框时,我收到错误??? Undefined function or variable 'hObject'.
所以我放弃了,并解决了它
我找到了两个不理想的解决方案来解决此问题。 第一种是在 GUIDE 中创建一个带有标签 cb_hidden
的不可见复选框。 然后我能够使用以下代码。
callback = get(objhandles.cb_hidden, 'callback');
set(objhandles.cb_r1_c1,'callback',callback);
这正确地将cb_r1_c1
的回调设置为与 cb_hidden
相同的回调。 通过这种方式,我能够将所有复选框回调重定向到这个虚拟复选框,然后从那里调用foo_cb_callback(hObject)
.
但是,此解决方案并不理想,因为它需要在 GUI 中的某个位置隐藏复选框。
另一种解决方法
由于我在运行时为每个复选框创建唯一的标记,因此我决定将标记直接写入回调字符串中。
tagstr = 'cb_r1_c1';
uicontrol(objhandles.mainfig, 'Style','checkbox','Tag',tagstr,'callback', 'foo_cb_callback(''' tagstr '''));
这会将回调设置为 foo_cb_callback('cb_r1_c1')
,以正确调用foo_cb_callback()
并将字符串传递'cb_r1_c1'
。 foo_cb_callback()
的前几行看起来像这样
function foo_cb_callback(tag)
global gdata
hObject = gdata.objhandles.(tag);
从那里,我几乎可以做任何我使用理想解决方案可以做的事情。 但是,此解决方案仍然不理想,因为我无法传入变量(除了不变的字符串(。 另外,我真的很想知道这样做的正确方法,我相信有一天我会找到它的用途。
像这样简单的东西不起作用吗?
function myCallback(src, event)
disp('myCallback called');
end
set(hObject, 'callback', @myCallback);
你先尝试的,
callbackstr = '@(hObject,eventdata)testfuig(''foo_cb_callback'',hObject,eventdata,guidata(hObject))';
set(objhandles.cb_r1_c1,'callback',callbackstr);
非常接近。您只需要设置字符串,而是设置函数句柄(在您的情况下为匿名函数(:
callbackFun = @(hObject,eventdata)testfuig('foo_cb_callback',hObject,eventdata,guidata(hObject));
set(objhandles.cb_r1_c1,'callback',callbackFun);
另外,它真的应该说testfuig
吗?