MATLAB.Exponenta
–Û·Ë͇ Matlab&Toolboxes

Приложения с GUI и дескрипторная графика

Свойства графических окон

Расположение и вид графических окон

При выводе результатов в графические окна сразу же возникает вопрос о задании положения и размеров графических окон на экране. Они определяются значением свойства Position графического окна, которое является вектором [x y width height]. Здесь x и y - координаты нижнего левого угла рабочей области окна, а width и height - ширина и высота рабочей области, соответственно. По умолчанию, единицы измерения - пиксели (можно выбрать и другие, установив свойство окна Units в подходящее значение: 'normalized', 'inches', 'centimeters', 'points', 'characters'). Слова "рабочая область" означают, что берется часть окна, ограниченная рамкой и заголовком. В присутствии рамки легко убедиться, создав графическое окно белого цвета и без строки меню и панели инструментов с использованием свойств Color и MenuBar:

hF = figure('Color', 'w', 'MenuBar', 'none')

Теперь рамка видна (см. рис. 1)

Рис. 1. Смысл свойства Position графического окна

Толщина левой, нижней и правой границы рамки 5 пикселей, а под заголовок отведено 30 пикселей. Этих сведений, однако, недостаточно для расположения графического окна - необходимо знать еще и текущие размеры экрана монитора в пикселях. Для этого придется прибегнуть к предку графического окна - корневому объекту Root, свойства которого служат для определения системных настроек компьютера и значений, принятых в MatLab по умолчанию. Указатель на объект Root всегда равен нулю. В нашем примере необходимо обратиться к свойству ScreenSize объекта Root, значением которого является вектор с координатами левого нижнего угла монитора, его ширины и высоты (по умолчанию, в пикселях):

scrsize = get(0, 'ScreenSize')
scrsize =
           1           1        1024         768

Несложные вычисления с его элементами scrsize(1), scrsize(2), scrsize(3) и scrsize(4), толщиной рамки (5 пикселей) и шириной заголовка (30 пикселей) позволяют расположить графическое окно нужного размера в подходящем месте экрана монитора. Пример приведен в справочной системе MatLab в разделе: "MATLAB> Graphics> Figure Properties> Positioning Figures> Example -- Specifying Figure Position".

Свойство MenuBar графического окна может принимать только два значения: 'on' или 'off', что приводит к отображению или скрытию одновременно панели инструментов и меню. Обсудим теперь, как управлять ими по отдельности, например, как получить графическое окно без панели инструментов, содержащее только меню, или наоборот - только панель инструментов. Для этого обращаются к свойству ToolBar, принимающему значения: 'none' (убрать панель инструментов) и 'figure' (добавить панель инструментов, как по умолчанию). Например:

hF=figure('ToolBar', 'figure', 'MenuBar', 'none')

приводит к появлению окна только с панелью инструментов, а

hF=figure('ToolBar','none')

к созданию окна только со строкой меню (см. рис. 2).

Для задания заголовка графического окна служат два его свойства Name и NumberTitle. Значение NumberTitle отвечает за вывод слова Figure и номера окна: 'on' - выводить (по умолчанию), 'off' - не выводить. Значением свойства Name может быть текстовая строка. Эти два свойства позволяют оформить заголовок графического окна по своему усмотрению, например:

hF = figure('NumberTitle', 'off', 'Name', 'Исходные данные')

Разберем теперь несколько более сложный вопрос, как оставить только нужные меню и кнопки на панели инструментов. Создайте графическое окно и сохраните указатель на него в переменной hF:

hF = figure;

Используйте теперь функцию allchild для получения потомков графического окна (в следующих разделах мы рассмотрим этот вопрос подробнее):

hFC = allchild(hF)

Оказывается, что у графического окна 9 потомков, в вектор hFC занесены указатели на них (числовые значения могут отличатся от приводимых ниже):

hFC =
  132.0026
  120.0026
  118.0026
   78.0026
   62.0026
   55.0026
   36.0026
   15.0026
    0.0026

Выясните теперь тип каждого из потомков, выводя значение его свойства Type:

get(hFC, 'Type')
ans = 
    'uimenu'
    'uimenu'
    'uimenu'
    'uimenu'
    'uimenu'
    'uimenu'
    'uimenu'
    'uimenu'
    'uitoolbar'

Итак, первые 8 потомков - меню окна, а последний из них - панель инструментов. Свойства объектов типа uimenu и uitoolbar и других элементов управления будут подробно рассмотрены в разделе, посвященном приложениям с графическим интерфейсом пользователя. Сейчас мы прибегнем только к одному из них Visible, которое отвечает за отображение соответствующего объекта и может принимать значения 'on' или 'off'.

Занесем указатели на меню в вектор hFMenu, а указатель на панель инструментов в вектор hFToolBar:

hFMenu = hFC(1:length(hFC)-1);
hFToolBar = hFC(end);

Для того, чтобы узнать соответствие указателей на меню c самими меню, следует прибегнуть к их свойству Label:

get(hFMenu, 'Label')

Оказывается, то hFMenu(1) - указатель на меню Help, hFMenu(2) - указатель на меню Window и т. д.

ans = 
    '&Help'
    '&Window'
    '&Desktop'
    '&Tools'
    '&Insert'
    '&View'
    '&Edit'
    '&File'

Значит, для скрытия, например меню Help, Window, Desktop, Insert и Edit достаточно выполнить:

set([hFMenu(1:3); hFMenu(5); hFMenu(7)] ,'Visible', 'off')

Аналогичным образом можно распорядиться и кнопками на панели инструментов - ее потомками. Но сначала необходимо получить указатели на них, снова при помощи allchild:

hTools = allchild(hFToolBar)

hTools =
   14.0011
   13.0011
   12.0011
   11.0011
   10.0011
    9.0011
    8.0011
    7.0011
    6.0011
    5.0011
    4.0011
    3.0011
    2.0011
    1.0011

Элементов вектора hTools ровно столько, сколько кнопок на панели инструментов, причем hTools(1) является указателем на Show Plot Tools, hTools(2) - Hide Plot Tools и т. д., а hTools(end) - указатель на New Figure. Предположим, что требуется оставить только инструменты увеличения и уменьшения масштаба и поворота. Тогда скрываем остальные:

set([hTools(1:5); hTools(7); hTools(10:end)], 'Visible', 'off')

В результате получается окно, приведенное на рис. 3.

Примечание

Неплохо бы еще скрыть оставшиеся разделители. За их наличие отвечает свойство Separator кнопки. Установка его значения в 'on' отображает разделитель слева от кнопки, а в 'off' - скрывает.

Для запрета изменения размеров окна пользователем и встраивания его в рабочую среду предназначены, соответственно, свойства Resize и DockControls. Их значениями может быть 'on' или 'off', например:

hF = figure('Resize', 'off', 'DockControls', 'off')

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

Если же Ваше приложение должно создавать графическое окно, встроенное в рабочую среду, или встраивать его в ходе работы, то необходимо воспользоваться свойством WindowStyle. Его значение 'docked' соответствует встроенному окну:

hF = figure('WindowStyle', 'docked')

Для отделения графического окна из рабочей среды следует установить WindowStyle в 'normal':

set(hF, 'WindowStyle', 'normal')

Свойство WindowStyle может принимать также значение 'modal', которое делает графическое окно модальным. Этот вопрос мы обсудим в разделе, посвященном приложениям с графическим интерфейсом пользователя.

Способы графического вывода

Как мы уже упоминали, высокоуровневые графические функции plot, mesh, surf и др. создают графическое окно, оси и размещают на них графический объект, или же выводят график на имеющиеся оси. Рассмотрим этот вопрос более подробно, какие свойства графического окна и осей отвечают за способ вывода нового графического объекта.

Эти свойства носят одинаковое название NextPlot и для графического окна, и для осей. В зависимости от их значений происходит либо вывод графика на существующие оси графического окна, либо создаются новые оси, а имеющиеся остаются или исчезают.

Если свойство NextPlot текущего графического окна имеет значение:

  • 'add' (по умолчанию), то в окно добавляются новые оси для графического вывода;
  • 'replace', то удаляются все потомки графического окна, указатели на которые не являются скрытыми, и все свойства окна (кроме Position и Units) принимают значение по умолчанию;
  • 'replacechildren', то удаляются все потомки окна, указатели на которые не являются скрытыми, а все свойства окна сохраняют свои значения;

Примечание

Скрытые указатели на графические объекты мы рассмотрим позже, но обычно указатели на оси не являются скрытыми, поскольку по умолчанию значением их свойства HandleVisibility является 'on'. Вектор указателей на потомков графического окна является значением свойства Children. В нем записаны указатели, не являющиеся скрытыми. При создании окна (без осей) таких объектов нет, поэтому значением Children является пустой массив. Именно поэтому выше нам пришлось прибегнуть к функции allchild, которая возвращает все указатели на потомков, включая скрытые.

Установка свойства NextPlot текущего графического окна в 'replace' эквивалентна вызову функции clf('reset'), а в 'replacechildren' - clf.

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

hF = figure;
hA1 = axes;
surf(peaks(30))
hA2 = axes;
mesh(peaks(30))
axes(hA1)
axes(hA2)

Способ графического вывода зависит также и от значения свойства NextPlot текущих осей. Если NextPlot:

  • 'add', то новый график добавляется на них;
  • 'replace' (по умолчанию), то удаляются все потомки осей и свойства осей (кроме Position, Units, PaperPosition и PaperUnits) приобретают установленные по умолчанию значения;
  • 'replacechildren', то удаляются все потомки осей, но свойства осей остаются неизменными.

Установка свойства осей NextPlot в 'replace' эквивалентно вызову функции cla('reset'), а в 'replacechildren' - cla.

Итак, если сформировано графическое окно и оси нужного вида, который не требуется изменять, то имеет смысл установить их свойства NextPlot в 'replacechildren'.

Цветовая палитра

При выводе поверхностей и полигональных объектов на оси графического окна возможно несколько способов их цветовой закраски - явное указание цвета ячеек и ребер в формате RGB и задание индексированного цвета, т.е. одного из определенных в текущей палитре цвета графического окна. Сейчас мы рассмотрим второй способ - использование палитры.

Палитра формируется для графического окна и сколько бы пар осей оно не содержало, все равно для каждой из них будет использоваться одна и та же заданная палитра. Палитра задается матрицей с тремя столбцами, каждая строка которой содержит цвет в формате RGB. Элементы строки задают интенсивность соответствующего цвета и должны принадлежать [0, 1] (0 - минимальная интенсивность, 1 - максимальная).

Имеется ряд предопределенных палитр: autumn, bone, colorcube, cool, copper, flag, hot, hsv, jet (по умолчанию), lines, pink, spring, summer, white и winter. Способ изменения цвета, принятый в этих палитрах описан в справочной системе в разделе с информацией о функции colormap. Для получения наглядного представления об этих палитрах проще всего установить палитру окна и воспользоваться командой colorbar:

figure
colormap(autumn)
colorbar

Функция rgbplot выводит график, показывающий доли красного, зеленого и синего в цветах палитры:

rgbplot(hsv)

Каждая из предопределенных палитр по умолчанию содержит 64 цвета или оттенка, что может быть изменено на значение не превосходящее 256 (для MS-Windows), например:

colormap(gray(4))

Залитая цветом поверхность создается высокоуровневыми функциями surf и др., либо низкоуровневой surface. При этом, если цвет не задан, то по умолчанию цвет закраски ячеек поверхности зависит от высоты ячейки (т.е. от значения визуализируемой сеточной функции). Наименьшее значение соответствует первому заданному цвету палитры, а наибольшее - последнему. Промежуточные значения определяются путем линейной интерполяции так, как показано на рис. 4.

Рис.4. Соответствие значения функции и цвета палитры.

Примечание

Такой способ отображения принят по умолчанию. Он может также зависеть от свойств осей и поверхности. Этот вопрос, а также управление прозрачностью объектов, мы разберем после обзора основных свойств поверхностей.

Для создания собственной цветовой палитры графического окна следует задать соответствующую матрицу и указать ее в качестве значения свойства ColorMap. Например, последовательность команд

[X, Y] = meshgrid(-2:0.1:2);
Z = X + Y + sin(pi*X).*cos(pi*Y);
hF = figure;
surf(X, Y, Z)
c = 1./(1:0.01:3)';
CM = [zeros(size(c)) c zeros(size(c))];
set(hF, 'ColorMap', CM)

приводит к палитре, содержащей только оттенки зеленого цвета (см. рис. 5)

Рис. 5. Пример создания палитры с оттенками зеленого цвета.

Печать графического окна

Название ряда свойств графического окна начинаются со слова Paper, очевидно, что они отвечают за способ печати графических окон.

Несколько свойств предназначены для задания размеров и ориентации листа бумаги.

  • PaperUnits - единицы измерения для задания размеров листа бумаги и положения графического окна, которые отсчитываются от нижнего левого угла. Значениями свойства PaperUnits может быть: 'normalized' (высота и ширина листа равны единице), 'inches' (дюймы, по умолчанию), 'centimeters' (сантиметры) или points (пункты, 1пт =1/72 дюйма).
  • PaperSize - размеры листа бумаги. Его значением является вектор из двух элементов [width height], задающих, соответственно, ширину и высоту листа в единицах, указанных в PaperUnits. Вместо задания размера, можно выбрать один из предопределенных: 'A0', 'A1', 'A2', 'A3', 'A4' и др. (их много), воспользовавшись свойством PaperType (по умолчанию его значение 'A4'). Изменение PaperType приводит к автоматическому изменению PaperSize, а изменение PaperSize влечет установку PaperType в 'custom'.
  • PaperOrientation - 'portrait' (по умолчанию), или landscape.

Следующие свойства служат для определения положения и вида графического окна на листе бумаги.

  • PaperPosition - вектор из четырех элементов [left, bottom, width, height], задающих координаты нижнего левого угла, ширину и высоту в единицах измерения, установленных в PaperUnits. Для расположения графического окна с указателем hF на всей области листа с полями по 1/4 дюйма проще всего воспользоваться функцией orient: orient(hF, 'tall').
  • PaperPositionMode - способ вывода графического окна на печать. Может принимать значения: 'auto' (тогда в центре листа печатается окно того же размера, что и на экране), или 'manual' (по умолчанию, при этом размер при печати определяется значением PaperPosition).
  • InvertHardcopy - при печати фон окна и осей становится белым, если это свойство принимает значение 'on' (по умолчанию). Значение 'off' соответствует печати с сохранением цветов.

Данные свойства позволяют задать опции печати и в сочетании с последующим применением команд print, printopt, printdlg, printpreview организовать печать графических результатов, например:

hF1=figure
mesh(peaks(30))
printpreview(hF1)

Все эти команды работают с одним графическим окном (текущим, по умолчанию, если не задавать указатель). Предположим, что Ваше приложение выводит графики в разные окна и пользователь выбирает несколько из них для печати на одном листе. Рассмотрим один из возможных способов на примере двух графических окон, первое из которых содержит оси с графиком поверхности, а второе - оси со столбцевой диаграммой:

hF1 = figure; 
hA1 = axes;
mesh(peaks(30))
hF2 = figure;
hA2 = axes;
bar3(rand(3))

В некотором месте программы требуется напечатать содержимое осей с указателями hA1 и hA2 на одном листе. Для этого:

1) создаем невидимое графическое окно с указателем hFTemp;
2) копируем оси (вместе с их потомками) с указателем hA1 в графическое окно hFTemp, пользуясь функцией copyobj, получаем новые оси с указателем hA1Temp;
3) задаем размеры hA1Temp осей при помощи свойства OuterPosition так, чтобы они занимали левую половину окна hFTemp;
4) аналогично поступаем с осями hA2, скопированные вместе с содержимым оси hA2Temp размещаем в правой половине графического окна hFTemp;
5) вызываем, например, функцию printpreview для предварительного просмотра и печати.

hFTemp = figure('Visible', 'off');
hA1Temp = copyobj(hA1, hFTemp)
set(hA1Temp, 'OuterPosition', [0 0 0.5 1])
hA2Temp = copyobj(hA2, hFTemp)
set(hA2Temp, 'OuterPosition', [0.5 0 0.5 1])
printpreview(hFTemp)

В конце программы вспомогательное окно можно удалить при помощи delete(hFTemp).

Примечание

Функция copyobj служит для копирования объекта вместе с потомками. Обращение к ней выглядит следующим образом:

hNew = copyobj(hOld, hParent),

где hOld - указатель на копируемый объект, hParent - предок для нового объекта, hNew - указатель на новый объект. При использовании copyobj необходимо следить за иерархией объектов: оси могут быть скопированы только на графическое окно, поверхности и линии только на оси. Например, последовательность команд:

hF = figure
hS = surf(peaks(50))
hF1 = figure
hS1 = copyobj(hS,hF1)

приведет к ошибке!


Поиск по сайту:

Система Orphus

Яндекс.Метрика