Использование addlister в графическом интерфейсе MATLAB, похоже, удаляет существующие дескрипторы

Я новичок в программировании графического интерфейса MATLAB (использую GUIDE, извините), и у меня есть следующая проблема: графический интерфейс отображает на оси последовательность изображений, хранящуюся в массиве ячеек. У меня есть пара кнопок и ползунок для прокрутки последовательности. Чтобы получить «непрерывный слайдер», я использую прослушиватель, который работает, но создает некоторые проблемы:

1) Когда я нажимаю ползунок, создается фигура и в ней отображается первый кадр последовательности, но при перемещении ползунка последовательность отображается по оси моего графического интерфейса (что я и хочу) и фигура становится пустым. Кто-нибудь может сказать мне, почему эта фигура создана и как я могу ее избежать?

2) Как только я нажимаю кнопку ползунка и, таким образом, использую прослушиватель, все ручки внутри графического интерфейса не работают, поскольку Matlab не распознает их, и я застрял с функциональным ползунком/дисплеем, но я не могу использовать кнопки.

Любые идеи о том, почему это происходит? Вот код, который я использую в функции создания слайдера:

function slider2_Frame_Video_Callback(hObject, eventdata, handles)

hListener = addlistener(hObject,'ContinuousValueChange',@(a,b) slider2_Frame_Video_Callback(hObject, eventdata, handles)); % a and b are dummy arguments

guidata(hObject,handles)

В обратном вызове ползунка код выглядит так (в основном imshow на текущей оси):

axes(hAxis)
imshow(Movie{frame},'parent',hAxis);

drawnow

% Это тоже не работает, так как handles.edit_FrameNumber не распознается Matlab

set(handles.edit_FrameNumber, 'String', frame);

guidata(hObject,handles);

Любые подсказки приветствуются спасибо!


person Benoit_11    schedule 02.06.2014    source источник
comment
Хорошо, спасибо, Джефф, ты прав! Также, если я использую внешнюю функцию для непрерывного отображения текущего кадра (вместо обратного вызова ползунка), кажется, что это работает. Массив ячеек Movie хранится в структуре, содержащей все глобальные переменные, которые я разделяю между обратными вызовами, используя setappdata/getappdata; это не позволяет мне объявлять переменные как «глобальные» в начале каждого обратного вызова. Кроме того, если это может помочь кому-то, кто читает это, рисунок, который появился за пределами графического интерфейса, когда я использовал прослушиватель, был связан с моим вызовом «gca» незадолго до этого.   -  person Benoit_11    schedule 04.06.2014


Ответы (1)


Интересно, часть проблемы заключается в том, что прослушиватель создается каждый раз, когда пользователь перемещает ползунок, поскольку код прослушивателя находится внутри этого обратного вызова И что обратный вызов предоставляется слушателю (похоже на какое-то странное туда-сюда? там). Таким образом, каждый раз, когда пользователь отпускает кнопку мыши после слайда, создается новый слушатель. Это может вызвать некоторые проблемы с другими кнопками, которые не реагируют.

Вместо того, чтобы создавать экземпляр слушателя, я бы сделал это в Opening_Fcn вашего графического интерфейса:

% --- Executes just before frameSlider is made visible.
function frameSlider_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 frameSlider (see VARARGIN)

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

if ~isfield(handles,'hListener')
    handles.hListener = ...
        addlistener(handles.slider1,'ContinuousValueChange',@respondToContSlideCallback);
end

% Update handles structure
guidata(hObject, handles);

Мой графический интерфейс называется frameSlider; у тебя будет что-то другое. В приведенном выше примере создается один прослушиватель с обратным вызовом функции, которую вам нужно будет определить в том же файле *.m, respondToContSlideCallback.

Образец тела для обратного вызова, который должен реагировать на непрерывный слайд:

% --- Executes on slider movement.
function respondToContSlideCallback(hObject, eventdata)
% hObject    handle to slider1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

% first we need the handles structure which we can get from hObject
handles = guidata(hObject);

% test to display the current value along the slider
disp(['at slider coordinate ' num2str(get(hObject,'Value'))]);

Если вы запустите этот код, командное окно будет постоянно отображать координаты ползунка, когда вы перемещаете ползунок из конца в конец.

В приведенном выше коде есть массив ячеек Movies. Как к этому обращается ваш обратный вызов? Это глобальная переменная или..? Откуда hist? Если Movies является результатом вызова какой-либо другой функции, то его можно сохранить и в handles (в зависимости от того, куда он загружается из файла). Я полагаю, вам также придется сопоставить координаты ползунка с количеством кадров, которые у вас есть (хотя, может быть, вы уже сделали это?).

person Geoff    schedule 02.06.2014