【问题标题】:Matlab GUI Callback Start and CompletionMatlab GUI 回调开始和完成
【发布时间】:2016-08-11 01:29:53
【问题描述】:

是否有一种通用方法来确定 Matlab GUI 回调函数何时开始然后返回到调度程序?

我想在回调运行完成时锁定用户交互,并在回调运行时显示忙碌状态。是否有可访问的调度程序,我可以在其中插入此代码,还是必须将其放入每个回调函数中。

我知道模态 waitbar 但我想尽可能避免使用它。 (他们不能被优雅地杀死。)

【问题讨论】:

  • 我尝试了以下即兴创作,为每个回调添加了包装函数:A = findall(0, 'Type', 'UIControl');for i = 1:length(A)set(A(i), 'Callback', {@wrapper, A(i).Callback});end
  • 当包装函数为:function wrapper(ObjH, EventData, origCallback)disp('Wrapper called!');feval(origCallback, ObjH, EventData);
  • 我认为,如果您想要一段代码在任何回调运行时执行,您将必须自己实现调度程序:所有回调都指向同一个调度程序函数(带有一个标识符参数)。调度程序显示“忙碌”,然后调用实际预期的回调函数。当函数返回调度程序时,显示“就绪”然后返回...如果可以同时触发多个回调,您将不得不观看re-entrancy 案例...

标签: matlab matlab-guide


【解决方案1】:

我建议添加一个包装函数,它包装所有原始 UIControl 回调函数。
包装函数执行以下操作:

  • 锁定(禁用)所有 GUI UIControl 对象。
  • 执行原始回调函数。
  • 在原始回调返回后启用所有 GUI UIControl。

您还可以在原始回调之前启动计时器,并在回调返回时停止计时器(计时器可以使用内置到主 GUI 的图像模拟等待栏[小轴内的图像])。

示例(假设 GUI 是使用guide 工具创建的):

% --- Executes just before untitled1 is made visible.
function untitled1_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to untitled1 (see VARARGIN)

% Choose default command line output for untitled1
handles.output = hObject;

%Add wrapper function to each UIControl callback.
A = findall(hObject.Parent, 'Type', 'UIControl');
for i = 1:length(A)
    set(A(i), 'Callback', {@wrapper, A(i).Callback});
end

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes untitled1 wait for user response (see UIRESUME)
% uiwait(handles.figure1);


function wrapper(ObjH, EventData, origCallback)
disp('Do somthing before callback begins...');
%You can also start a timer.

%Disable all UIControl objects, before executing original callback
A = findall(ObjH.Parent, 'Type', 'UIControl');
for i = 1:length(A)
    set(A(i), 'Enable', 'off');
end

%Execute original callback.
feval(origCallback, ObjH, EventData);

disp('Do somthing after callback ends...');
%You can also stop the timer.

%Enable all UIControl objects, after executing original callback
for i = 1:length(A)
    set(A(i), 'Enable', 'on');
end


% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
pause(1);
set(handles.pushbutton1, 'BackgroundColor', [rand(1,1), rand(1,1), rand(1,1)]);

【讨论】:

  • 这很好用。感谢您展示完整的解决方案。
  • 我做了一处改动。而不是 A = findall(hObject, 'Type', 'UIControl');,我使用 A = findall(hObject.Parent, 'Type', 'UIControl'); 这是禁用所有 UICONTROL 所需要的。
  • 我修改了示例,谢谢。备注:我原来用的是findall(0, 'Type', 'UIControl');
【解决方案2】:

您通常可以使用waitfor 命令锁定用户交互。它旨在完全按照您的要求进行。

您可以让您的回调函数在完成后更新句柄属性,这会导致waitfor 退出。如果您正在更新的句柄属性也恰好保存了tic / toc 操作的结果,该操作计时了您的回调函数的持续时间,那么您用一块石头杀死了两只鸟:)

【讨论】:

  • waitfor 非常简单......但如果不清楚,我们很乐意提供一个例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-25
  • 1970-01-01
  • 2015-10-13
相关资源
最近更新 更多