Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
gui.doc
Скачиваний:
19
Добавлен:
22.11.2018
Размер:
261.63 Кб
Скачать

3.5. Диалоговые окна и меню приложения

Пакет MatLab предоставляет разработчику приложения возможность использовать стандартные диалоговые окна.

3.5.1 Окно подтверждения

Некоторые действия приложения требуют подтверждения пользователя. Например, пользователь нашего приложения может случайно нажать кнопку «Очистить», предназначенную для очистки графика. Следует вывести диалоговое окно, в котором пользователь подтвердит, действительно ли требуется очистить график.

Диалоговое окно подтверждения создается функцией questdlg, которая в самом простом случае имеет два входных параметра - строки с текстом внутри диалогового окна и заголовок окна, окно, создаваемое таким образом, имеет три кнопки - Yes, No и Cancel. Выбор пользователя возвращается в строковом выходном аргументе функции questdlg, его значение совпадает с надписью на кнопке.

Усовершенствуйте обработчик кнопки «Очистить» так, чтобы соответствующие операторы выполнялись только в том случае, если пользователь нажал кнопку Yes в появляющемся диалоговом окне с текстом «Очистить график?» и заголовком «mygui».

Листинг 20. Измененный обработчик кнопки «Очистить». mygui.m:\

function clear_Callback(hObject, eventdata, handles)

plotClearDialog(hObject, handles) ;

Листинг 21. Дописываем заглушку. plotClearDialog.m:

function plotClearDialog(hObject, handles)

yesButton = 'Да';

noButton = 'Нет';

message = 'Очистить график';

button = questdlg(message, 'mygui', yesButton, noButton, noButton);

if strcmp(button, yesButton)

cla

set(handles.axMain, 'YGrid', mapValue(handles.chbxGridY, 'Value'))

set(handles.axMain, 'XGrid', mapValue(handles.chbxGridX, 'Value'))

set(handles.mnGraphClear,'Enable','off');

set(handles.mnGraphPlot,'Enable','on');

set(handles.clear,'Enable','off');

set(handles.btnPlot,'Enable','on');

end

3.5.2 Окно с сообщением об ошибке

Функция errordlg предназначена для создания диалогового окна с сообщением об ошибке. Входными аргументами errordlg являются строки с текстом и заголовком окна.

Дополните построение графика данных вызовом диалогового окна с выбором источника входных данные: его устроят данные по умолчанию, если он не пожелает ввести их из файла. В качестве файла по умолчанию можно задать файл files\data.mat. В том случае, если пользователь пожелает ввести данные из файла, должен быть прочитан вектор «mymatrix». Проверьте размерность и тип содержимого массива при помощи функций size, ndims и isnumeric и выведите сообщение в случае несоответствующего формата данных.

3.5.3 Сериализация и маршалинг

В информатике маршалинг (от англ. marshal — упорядочивать, по смыслу похоже на сериализацию) — процесс преобразования представления объекта в памяти в формат данных, пригодный для хранения или передачи. Обычно применяется, когда данные необходимо передавать между различными частями одной программы или от одной программы к другой. Противоположный процесс называется демаршалингом (также называемый десериализацией).

Маршалинг отличается от сериализации тем, что маршалинг ориентирован на удаленные друг от друга объекты.

Matlab предоставляет возможность сохранять и загружать объекты в двоичном или текстовом формате. Изучите команды save и load, сохраните входные данные в файле files\data.mat, как было сказано выше имя сохраняемого вектора должно быть «mymatrix».

Внесите изменения в функцию прорисовки графика как показано в листинге 19.

Листинг 22. Диалог выбора источника данных для графика. plotDialog.m:

function plotDialog(hObject, handles)

default = 'По умолчанию';

fromFile = 'Из файла';

userInput = 'Пользовательский ввод';

errorMessage = 'Неизвестный формат файла с данными';

errorCaption = 'Ошибка!';

dialogCaption = 'Источник данных';

% dataFile - имя файла с сериализованными данными

dataFile = 'files\data.mat';

result = questdlg(dialogCaption, 'mygui', default, fromFile, userInput, default);

if strcmp(result, fromFile)

try

% восстановление начального состояния данных из

% битовой последовательности.

load(dataFile);

catch

errordlg(errorMessage, errorCaption)

end

arraySize = size(mymatrix);

if(ndims(mymatrix) ~= 2 | ~isnumeric(mymatrix))

errordlg(errorMessage, errorCaption)

end

x = mymatrix;

y = exp(-mymatrix.^2);

end

if strcmp(result, userInput)

try

x = [ -2.5 : 0.6 : 2 ];

y = sym(get(handles.userFunction, 'String'));

y = subs(y);

catch

errordlg('Ошибка разбора пользовательской функции', errorCaption)

end

end

if strcmp(result, default)

x = [ -2.5 : 0.6 : 2 ];

y = exp(-x.^2); end

drawPlot(x, y, handles)

set(handles.axMain, 'YGrid', mapValue(handles.chbxGridY, 'Value'))

set(handles.axMain, 'XGrid', mapValue(handles.chbxGridX, 'Value'))

В крупных проектах не принято хранить текстовые константы и сообщения в файле с исходным кодом, но мы пренебрежем этой практикой.

3.5.4 Меню графического окна

Пакет MatLab дает возможность программисту использовать контекстные и оконные меню. Свойство MenuBar окна приложения (объекта figure) отвечает за наличие стандартных меню File, Edit, Tools, Window и Help в работающем приложении. Размещение и программирование меню производится при помощи редактора меню.

3.5.5 Оконные меню

Перейдите в режим редактирования приложения в среде GUIDE. Принцип конструирования меню проще всего понять, создавая новое меню. Запустите редактор меню из панели управления (или выбором пункта меню Tools->Menu Editor…), появляется окно Menu Editor (рисунок слева).

Окно редактора меню содержит две вкладки: Menu Bar, предназначенную для создания строки меню приложения, и Context Menus для контекстного меню. Области навигатора и свойств элементов меню пока пустые. Создайте меню, нажав соответствующую кнопку на панели инструментов редактора меню (убедитесь, что выбрана вкладка Menu Bar), в навигаторе появилась строка Untitled 1, сделайте ее текущей щелчком мыши. В области свойств находятся строки ввода (рисунок справа).

Рис. 5. Окно редактирования меню

В поле Label задается надпись элемента, a Tag - для определения названия созданного объекта. Введите текст "График" в строку Label и задайте имя mnGraph. Запустите приложение и убедитесь в наличии меню График. Выбор меню График в работающем приложении не приводит к раскрытию меню, следует создать пункты меню. Перейдите в режим редактирования, сделайте текущей строку График в навигаторе редактора меню и добавьте пункт, нажав соответствующую кнопку на панели инструментов редактора меню. Установите надпись пункта «Построить» и дайте ему имя mnGraphPlot. Добавьте еще один пункт меню, сделав предварительно текущей строку График в навигаторе. Аналогичным образом задайте надпись «Очистить» и имя mnGraphClear. Навигатор меню должен содержать структуру, изображенную на рисунке. Меню График имеет первый уровень, а пункты «Построить», «Очистить» - второй.

Рис. 6. Добавление пунктов главного меню

Выбор меню График приводит к раскрытию меню. Пока при обращении к пунктам «Построить» и «Очистить» ничего не происходит, следует запрограммировать обработчики событий пунктов меню.

Листинг 23. Добавьте обработчики меню. mygui.m:

function mnGraphPlot_Callback(hObject, eventdata, handles)

plotDialog(hObject, handles)

set(handles.mnGraphPlot,'Enable','off');

set(handles.mnGraphClear,'Enable','on');

set(handles.BtnPlot,'Enable','off');

set(handles.clear,'Enable','on');

function mnGraphClear_Callback(hObject, eventdata, handles)

plotClearDialog(hObject, handles)

function mnGraph_Callback(hObject, eventdata, handles)

;

Листинг 24. Добавьте приведенный код в plotClearDialog.m:

set(handles.clear,'Enable','off');

set(handles.BtnPlot,'Enable','on');

3.5.6 Контекстные меню

Элементы управления, в том числе и созданные в ходе работы приложения, могут иметь собственное контекстное меню, которое доступны через нажатие ЛКМ. Конструирование контекстного меню состоит в создании его в редакторе меню, определении событий Callback пунктов меню и последующем связывании меню с объектом.

Перейдите к вкладке Context Menus в редакторе меню и нажмите кнопку создания контекстного меню, в навигаторе меню появляется строка для меню. Задайте ему имя cmLine. Обратите внимание, что на панели свойств нет строки ввода Label, т. к. раскрывающееся меню не должно иметь надписи. Создайте три пункта меню при помощи той же кнопки, что применяется для добавления пунктов меню окна приложения. Определите для них надписи синий, красный, зеленый и имена cmLineBlue, cmLineRed, cmLineGreen соответственно. В результате навигатор меню должен содержать структуру, приведенную на рисунке.

Рис. 7. Добавление пунктов контекстного меню

В работающем приложении щелчок правой кнопкой мыши по линии графика не приводит к отображению контекстного меню. Сейчас контекстное меню cmLine присутствует в приложении как объект, но другой объект - линия, создаваемая при нажатии, например, на кнопку «Построить», "не знает" о том, что у нее есть собственное контекстное меню. Следующий этапсостоит в связывании линии с созданным меню cmLine.

Любой объект, размещенный в окне приложения, имеет свойство UIContextMenu, значением которого может являться указатель на имеющееся контекстное меню. Для того чтобы созданный объект, т. е. линия графика, обладал контекстным меню, следует установить свойству UIContextMenu значение указателя на меню cmLine, содержащееся в структуре handles. Построение линии в приложении производится или при нажатии пользователем кнопки «Построить», или при выборе пункта «Построить» меню График.

Листинг 25. Обработчики контекстных меню. mygui.m:

function cmLineBlue_Callback(hObject, eventdata, handles)

set(handles.pmColor, 'Value', 1)

changeColor(handles)

function cmLineRed_Callback(hObject, eventdata, handles)

set(handles.pmColor, 'Value', 2)

changeColor(handles)

function cmLineGreen_Callback(hObject, eventdata, handles)

set(handles.pmColor, 'Value', 3)

changeColor(handles)

3.5.7 Ввод пользовательской функции

Добавьте на форму текстовое поле и надпись «Пользовательский ввод». С помощью этого поля пользователь сможет ввести функцию с клавиатуры, если введенная функция некорректна, следует вывести сообщение.

Листинг 26. Измененная функция прорисовки. plotDialog.m:

function plotDialog(hObject, handles)

default = 'По умолчанию';

fromFile = 'Из файла';

userInput = 'Пользовательский ввод';

errorMessage = 'Неизвестный формат файла с данными';

errorCaption = 'Ошибка!';

dialogCaption = 'Источник данных';

% dataFile - имя файла с сериализованными данными

dataFile = 'files\data.mat';

result = questdlg(dialogCaption, 'mygui', default, fromFile, userInput, default);

if strcmp(result, fromFile)

try

% восстановление начального состояния данных из

% битовой последовательности.

load(dataFile);

catch

errordlg(errorMessage, errorCaption)

end

arraySize = size(mymatrix);

if(ndims(mymatrix) ~= 2 | ~isnumeric(mymatrix))

errordlg(errorMessage, errorCaption)

end

x = mymatrix;

y = exp(-mymatrix.^2);

end

if strcmp(result, userInput)

try

x = [ -2.5 : 0.6 : 2 ];

y = sym(get(handles.userFunction, 'String'));

y = subs(y);

catch

errordlg('Ошибка разбора пользовательской функции', errorCaption)

end

end

if strcmp(result, default)

x = [ -2.5 : 0.6 : 2 ];

y = exp(-x.^2);

end

drawPlot(x, y, handles)

set(handles.axMain, 'YGrid', mapValue(handles.chbxGridY, 'Value'))

set(handles.axMain, 'XGrid', mapValue(handles.chbxGridX, 'Value'))

3.5.8 Тестирование

Задачей тестирования является выявление нежелательного поведения программы и проверка работоспособности. Вы должны еще раз протестировать все функции приложения вместе и все функции по отдельности. Проведите ревизию кода и определите потенциально некачественный код.