【问题标题】:Matlab guidata(hObject, handles) not updating flag in UI when called from listener从侦听器调用时,Matlab guidata(hObject,句柄)不更新 UI 中的标志
【发布时间】:2017-01-16 18:13:09
【问题描述】:

这是许多其他人遇到的类似问题,guidata(hOjbect, handles) 似乎没有更新值。我正在将它与侦听器一起使用,但不知道如何继续。

在我的gui_OpeningFcn 我有以下行:

addlistener(handles.s, 'name', 'PostSet', @(s,e)updatefilesave(hObject, [], handles));

这会适当地设置侦听器,并在修改名称时调用updatefilesave。但是,updatefilesave 内部是以下代码:

handles.fileUnsaved = true;
guidata(hObject, handles);

在函数内部,两条线都有效。当我在第一行和步骤上设置断点时,fileUnsaved 设置为 true。在我执行第二行之后(仍然在 updatefilesave 函数内),handles.fileUnsaved 仍然设置为 true。

但是,当我退出函数时,绿色箭头会出现在 gui_OpeningFcn 函数中的 addlistener 行上。在此级别,handles.fileUnsaved 现在设置回 false。

使用侦听器时如何获取要更新的句柄?

编辑

我要做的是知道输入字段何时发生更改,以便我可以提示用户在关闭程序之前保存他们的工作。我检查了 CloseRequestFcn 中的 fileUnsaved 标志,如果为真,我会在退出前询问用户是否要保存。

function namebox_Callback(hObject, eventdata, handles)

newName = handles.namebox.String;
if ~isempty(newName)
    handles.s.name = newName; % (listener gets triggered here post set)
end

handles.namebox.String = handles.s.name;

guidata(hObject, handles); % (namebox's local handles with fileUnsaved set to false gets put into hObject)

这就是为什么我不能在CloseRequestFcn 中调用handles = guidata(hObject)。阻止这种情况的唯一方法是在调用guidata(hObject, handles) 之前在名称框回调中调用handles = guidata(hObject)。但是在任何地方都这样做会破坏使用侦听器的意义。我会在每个回调函数(大约 50 个)中将 fileUnsaved 设置为 true。

【问题讨论】:

    标签: matlab matlab-figure matlab-guide


    【解决方案1】:

    一般来说,如果您希望从一个回调中调用一个函数来修改handles,然后让这些更改可用于调用函数,您不仅需要保存handles 结构在被调用函数中(以便它们可用于其他回调),但您必须在调用函数中重新加载 handles 结构,否则调用函数只会使用它自己的本地(且未修改)副本handles 因为它无法知道它被修改了。

    function main_callback(hObject, eventData, handles)
    
        % Set the value to one thing
        handles.value = false;
    
        sub_callback(hObject, eventData, handles);
    
        % Check that the value is STILL false
        disp(handles.value)
    
        % Load in the change so that handles gets updated
        handles = guidata(hObject);
    
    end
    
    function sub_callback(hObject, eventData, handles)
        handles.value = true;
    
        % Save the value
        guidata(hObject, handles);
    end
    

    另一种选择是让您的其他功能实际返回修改后的handles

    function handles = sub_callback(hObject, eventData, handles)
        handles.value = true;
    
        guidata(hObject, value);
    end
    

    然后在调用函数中,您可以使用输出参数覆盖本地 handles 变量

    handles = sub_callback(hObject, eventData, handles);
    

    现在谈谈您关于addlistener 的具体问题,由于回调是以“异步”的方式执行的,因此返回值实际上没有意义。不过,我建议重新加载handles 数据(如第一个示例所示),然后再再次使用handles(您希望更改它)以确保您拥有最新的-日期版本。

    【讨论】:

    • 这基本上意味着我必须修改 addlistener 行以包含某种handles = guidata(hObject) 调用。有没有办法在 addlistener 函数输入中嵌套多个函数调用?喜欢@(s,e)updatefilesave(hObject, [], handles);handles=guidata(hObject)
    • @toshiomagic 不。正如我在回答的最后一部分中所说,您不能从addlistener 返回值,并且由于它是异步执行的,因此将handles = guidata(hObject) 放入您的代码中 您分配监听器后将不起作用。在访问handles 之前,您需要将handles = guidata(hObject) 放入行中的代码中并期望它有所不同
    • 该死的。这基本上违背了听众的目的。如果我必须去每个s 更改的函数并说handles = guidata(hObject),我还不如去每个地方说handles.fileUnsaved = true
    • @toshiomagic 嗯,你在这里想要做什么有点不清楚。你能告诉我们你开场fcn的其余部分吗?我不确定你为什么需要在同一个函数中访问修改后的句柄,因为如果 handles.sname 属性发生变化,那意味着你明确地改变了它,不是吗?
    • 我正在尝试检测一些输入值何时发生更改。如果它们确实发生了变化,我希望将标志 fileUnsaved 设置为 true。这样,当用户尝试关闭 gui 而不保存最新更改时,系统会提示他们保存。我认为最简单的方法是添加一些监听器,它们都指向一个将fileUnsaved 设置为 true 的函数。
    【解决方案2】:

    我偶然发现这个线程有类似的问题,但对我来说,修改侦听器内部的句柄似乎是有效的。

    在外部函数中,我有这样的东西:

    handles.myListener = addlistener(ObjectThrowingEvent,'EventName', @(src,evt)ListenerFunction(src, evnt, hObject));
    guidata(hObject,handles);
    

    然后在里面函数

    function ListenerFunction(ObjectThrowingEvent, eventData, hObject)
      handles = guidata(hObject)
      % a bunch of stuff happens, including updates to the handles structure
      guidata(hObject, handles);
    

    在我看来,不同之处在于我传入 hObject 并在侦听器中从 hObject 查找句柄。即使侦听器是异步的,它也被传递 hObject 我认为它只是指向图形的当前状态,而不是一些本地未更新的副本。

    我很好奇这是否适合你。到目前为止,它似乎在我的代码中工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-17
      • 2014-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多