- •Лабораторная работа № 5 тема:«Создание приложений с gui без среды guide»
- •Простой пример - приложение с кнопкой и осями
- •Задание размеров окна приложения и элементов интерфейса
- •Задание дополнительных параметров в функциях обработки событий
- •Скрытие указателей объектов приложения с gui
- •Получение указателей на объекты приложения в функциях обработки событий, функция guihandles.
- •Сохранение данных, полученных в функции обработки событий, функция guidata.
- •Обмен данными между функциями обработки событий. Обработка событий объектов, создаваемых приложением.
- •Сохранение объектов приложения для повторных запусков.
- •Рисование кривых мышью
- •Перемещение объектов на осях мышью
- •Приложение с панелью переключателей для zoom и pan
Рисование кривых мышью
В MATLAB есть функция ginput, которая позволяет задавать точки на осях щелчком мыши и получить их координаты. В справочной системе в разделе Graphics: Creating Specialized Plots: Interactive Plotting приведен пример небольшого приложения, в котором заданные точки соединяются сплайном. В этом приложении предварительно требуется задать все точки и только затем построится сплайн. В этом разделе мы рассмотрим способ рисования кривых без использования функции ginput, при котором задание каждой новой точки сразу же приводит к перестроению проходящей через них кривой (см. рис. 1). Для добавления точек следует делать щелчок с удержанием Ctrl, а щелчок без Ctrl приводит к завершению соединения точек кривой.
Рис. 1. Рисование кривых мышью.
Алгоритм простой — при добавлении первой точки сплайн строить не нужно. Как только появляется вторая точка, следует построить сплайн, а при добавлении третьей, четвертой и т.д. точек нужно перестроить сплайн. Для сохранения данных (координат точек и указателя на линию) заведем структуру данных приложения Line, которую будем получать и сохранять при помощи функции guidata. Для обработки щелчка мыши запрограммируем возникающее при этом событие осей ButtonDownFcn в подфункции BtnDown. В ней проверим, что точка, в которой сделан щелчок, лежит в пределах осей. Координаты точки получим при помощи свойства CurrentPoint осей. Далее определим тип щелчка, для чего задействуем свойство SelectionType графического окна. При обычном щелчке мышью это свойство принимает значение ‘normal’, а при щелчке левой кнопкой с удержанием Ctrl — значение ‘alt’. Если был сделан обычный щелчок, то всем полям структуры Line присвоим пустые массивы, а если был сделан щелчок с удержанием Ctrl, то добавим в этой точке маркер, а координаты точки занесем в Line.X и Line.Y, после чего построим сплайн при помощи функции spline, удалим график предыдущего сплайна и построим график нового.
Иногда возможна ситуация, когда новая точка должна быть добавлена на существующей кривой. При щелчке по кривой событие ButtonDownFcn осей не возникает, поэтому после построения кривой в качестве обработки ее события ButtonDownFcn назначим ту же самую функцию BtnDown.
Ниже приведена функция plotcurve с подфункцией BtnDown.
function plotcurve
figure('Color', 'w') % создаем графическое окно
axes('XLim', [-1 1], 'YLim', [-1 1], 'Box', 'on', ...
'ButtonDownFcn', @BtnDown); % создаем оси
hold on
% заполняем структуру данных приложения
Line.X = []; % абсциссы точек
Line.Y = []; % ординаты точек
Line.h = []; % указатель на линию
guidata(gcf, Line) % сохраняем структуру данных
function BtnDown(src, eventdata)
% Подфункция обработки события щелчка по осям
% получаем координаты текущей точки
C = get(gca,'CurrentPoint');
x = C(1,1);
y = C(1,2);
% узнаем пределы осей
xlim = get(gca, 'XLim');
ylim = get(gca, 'YLim');
% проверяем, был ли щелчок в пределах осей
inaxes = xlim(1)< x & xlim(2) > x & ...
ylim(1)< y & ylim(2) > y;
if inaxes
% узнаем тип щелчка мышью
key = get(gcf, 'SelectionType');
if isequal(key, 'normal')
% обычный щелчок
% присваиваем всем полям структуры данных пустые массивы
Line = guidata(gcf);
Line.X = [];
Line.Y = [];
Line.h = [];
else
% добавляем координаты новой точки
Line = guidata(gcf);
Line.X = [Line.X x];
Line.Y = [Line.Y y];
% рисуем маркер
line(x, y, 'Marker','o', 'MarkerSize', 10,...
'MarkerFaceColor', 'c', 'MarkerEdgeColor', 'm');
% если точек больше одной, то строим сплайн
if length(Line.X) > 1
t = 1 : length(Line.X); % узлы сплайна
tt = 1: 0.1: t(end); % промежуточные точки для вычисления в них значения сплайна
sp = spline(t, [Line.X; Line.Y], tt);
% если есть линия, то удаляем ее
if ~isempty(Line.h)
delete(Line.h)
end
% рисуем новую линию
Line.h = plot(sp(1, :), sp(2, :), 'm');
set(Line.h, 'LineWidth', 2)
set(Line.h, 'ButtonDownFcn', @BtnDown)
end
end
% сохраняем структуру данных
guidata(gcf, Line)
end