- •Лабораторная работа № 5 тема:«Создание приложений с gui без среды guide»
- •Простой пример - приложение с кнопкой и осями
- •Задание размеров окна приложения и элементов интерфейса
- •Задание дополнительных параметров в функциях обработки событий
- •Скрытие указателей объектов приложения с gui
- •Получение указателей на объекты приложения в функциях обработки событий, функция guihandles.
- •Сохранение данных, полученных в функции обработки событий, функция guidata.
- •Обмен данными между функциями обработки событий. Обработка событий объектов, создаваемых приложением.
- •Сохранение объектов приложения для повторных запусков.
- •Рисование кривых мышью
- •Перемещение объектов на осях мышью
- •Приложение с панелью переключателей для zoom и pan
Перемещение объектов на осях мышью
Мы разберем простой способ организации передвижения объектов, нарисованных на осях, при помощи мыши. Ограничимся пока приложением movecrc, в котором на осях есть три кружка, для их перемещения используется мышь при нажатой левой кнопке (см. рис. 1). Далее немного модифицируем приложение, добавив в него возможность копирования кружков движением мыши при нажатой клавише Ctrl и удаление кружка двойным щелчком.
Рис. 1. Приложение movecrc для перемещения кружков мышью.
Приложение movecrc состоит из основной функции с подфункциями (их текст приведен ниже). В основной функции создаются:
графическое окно и оси с пределами по x и y от -1 до 1 и с рамкой вокруг;
три круглых маркера заданного размера и цвета при помощи функции line (в функции line указаны координаты одной точки, поэтому линии не будет, а будет только маркер), указатели на маркеры записываем в массив hM.
Далее с событием ButtonDownFcn каждого маркера (которое возникает при нажатии кнопки мыши, если курсор находится на маркере) в цикле связываем подфункцию MarkerButtonDownFcn.
Назначение подфункций приложения movecrc следующее.
MarkerButtonDownFcn(src, eventdata) — подфункция, вызываемая при нажатии кнопки мыши на маркере. В ней с событием графического окна WindowButtonMotionFcn (которое возникает при движении курсора мыши в пределах графического окна) связывается подфункция MouseMoving. В подфункцию MouseMoving передается дополнительный аргумент — указатель на маркер, который возвращается функцией gcbo (функция gcbo возвращает указатель на объект, событие которого выполняется в данный момент времени). Кроме этого, с событием графического окна WindowButtonUpFcn (которое возникает при отпускании кнопки мыши) связывается подфункция ButtonUp.
MouseMoving(src, eventdata, hM) — подфункция, выполняемая при движении курсора мыши. Ее третий аргумент hM содержит указатель на текущий (двигаемый) маркер. В этой подфункции при помощи свойства осей CurrentPoint узнаются текущие координаты курсора мыши, делается проверка на выход за пределы осей и изменяются координаты маркера.
ButtonUp(src, eventdata) — подфункция, выполняемая при отпускании кнопки мыши. В этой подфункции свойствам WindowButtonMotionFcn и WindowButtonUpFcn графического окна присваивается пустая строка для разрыва соответствующих событий с прежними функциями MouseMoving и ButtonUp.
function movecrc
% создаем графическое окно
figure('Color', 'w')
% создаем оси
axes('XLim', [-1 1], 'YLim', [-1 1], 'Box', 'on');
% Рисуем три маркера (линии)
hM(1)=line(0.5, 0.5, 'Marker','o', 'MarkerSize', 20,...
'MarkerFaceColor', 'r', 'MarkerEdgeColor', 'g');
hM(2)=line(-0.5, -0.5, 'Marker','o', 'MarkerSize', 20,...
'MarkerFaceColor', 'y', 'MarkerEdgeColor', 'b');
hM(3)=line(0, 0, 'Marker','o', 'MarkerSize', 20,...
'MarkerFaceColor', 'c', 'MarkerEdgeColor', 'm');
% определяем подфункцию обработки события ButtonDownFcn каждой линии
for k = 1 : length(hM)
set(hM(k),'ButtonDownFcn',@MarkerButtonDownFcn)
end
function MarkerButtonDownFcn(src,eventdata)
% Подфункция обработки события ButtonDownFcn линии
% Определяем подфункции для событий WindowButtonMotionFcn
% и WindowButtonUpFcn графического окна
set(gcf,'WindowButtonMotionFcn',{@MouseMoving,gcbo})
set(gcf,'WindowButtonUpFcn',@ButtonUp)
function MouseMoving(src,eventdata,hM)
% Подфункция для события WindowButtonMotionFcn
% получаем координаты текущей точки осей
C = get(gca, 'CurrentPoint');
x = C(1,1);
y = C(1,2);
% получаем пределы осей
xlim = get(gca, 'XLim');
ylim = get(gca, 'YLim');
% в inaxes 1, если не вышли за оси, иначе - 0
inaxes = xlim(1)< x & xlim(2) > x & ...
ylim(1)< y & ylim(2) > y;
if inaxes
% если находимся в пределах осей,
% то изменяем координаты маркера
set(hM,'XData', x, 'YData', y)
end
function ButtonUp(src, eventdata)
% Подфункция для события WindowButtonUpFcn
% Когда отпустили кнопку мыши, графическое окно должно перестать
% реагировать на движение мыши
set(gcf,'WindowButtonMotionFcn', '')
set(gcf,'WindowButtonUpFcn', '')
Небольшая модификация подфункции MarkerButtonDownFcn позволяет копировать маркеры (мышью при нажатой клавише Ctrl) и удалять их двойным щелчком. Для того, чтобы узнать тип щелчка используется свойство SelectionType графического окна. Это свойство принимает следующие значения.
normal — при обычном щелчке левой кнопкой;
extend — при щелчке левой кнопкой с удержанием Shift, или при щелчке одновременно двумя клавишами;
alt — при щелчке левой кнопкой с удержанием Ctrl, или при щелчке правой кнопкой
open — при двойном щелчке любой кнопкой.
После определения типа щелчка в подфункции MarkerButtonDownFcn происходит его обработка. Если был сделан щелчок с удержанием Ctrl, то маркер копируется при помощи функции copyobj. Ее первым входным аргументом является указатель на копируемый объект, вторым — указатель на объект, которому по иерархии принадлежит копируемый объект (оси), а в выходном аргументе возвращается указатель на новый объект. Далее с событием ButtonDownFcn нового маркера связывается функция MarkerButtonDownFcn. Если был сделан двойной щелчок, то удаляем маркер и завершаем работу подфункции при помощи return. Связывание с событиями WindowButtonMotionFcn и WindowButtonUpFcn соответствующих подфункций остается без изменений.
function MarkerButtonDownFcn(src,eventdata,hM)
% Подфункция обработки события ButtonDownFcn линии
% узнаем тип щелчка мышью
key = get(gcf, 'SelectionType');
if isequal(key, 'alt')
% если щелчок с Ctrl, то дублируем маркер
hM = copyobj(hM, gca)
% назначем подфункцию обработки его события ButtonDownFcn
set(hM, 'ButtonDownFcn', {@MarkerButtonDownFcn, hM})
end
if isequal(key, 'open')
% если двойной щелчок, то удаляем маркер
delete(hM)
% и завершаем работу подфункции
return
end
% Определяем подфункции для событий WindowButtonMotionFcn
% и WindowButtonUpFcn графического окна
set(gcf,'WindowButtonMotionFcn',{@MouseMoving,hM})
set(gcf,'WindowButtonUpFcn',@ButtonUp)