psSolid
|
Сплошная линия
|
psDash
|
Штриховая линия
|
psDot
|
Пунктирная
линия
|
psDashDot
|
Штрих-пунктирная
линия
|
psDashDotDot
|
Линия,
чередующая штрих и два пунктира
|
psClear
|
Отсутствие
линии
|
psInsideFrame
|
Сплошная линия,
но при Width > 1 допускающая цвета, отличные от палитры Windows
|
У канвы имеется свойство PenPos типа TPoint (см
<mk:@MSITStore:F:\Delphi\100comp.CHM::/3_2.htm>.). Это свойство
определяет в координатах канвы текущую позицию пера. Перемещение пера без
прорисовки линии, т.е. изменение PenPos, производится методом канвы MoveTo
(X,Y). Здесь (X, Y) - координаты точки, в которую перемещается перо.
Эта текущая точка становится исходной, от которой методом LineTo (X,Y) можно
провести линию в точку с координатами (X,Y). При этом текущая точка перемещается
в конечную точку линии и новый вызов LineTo будет проводить точку из
этой новой текущей точки.
Давайте попробуем нарисовать пером график синуса из предыдущего
примера. В данном случае обработчик события формы OnPaint может иметь
вид:
procedure
TForm1. FormPaint (Sender: TObject);
var,Y: real;
// координаты функции,PY: longint; // координаты пикселей
begin:
=clWhite;. MoveTo (0,ClientHeight div 2);
for PX: =0 to
ClientWidth do
begin
{X - аргумент графика,
соответствующий пикселю с координатой РХ}: = PX*4*Pi/ClientWidth;: = Sin (X);
{PY - координата пикселя,
соответствующая координате Y}: = trunc (ClientHeight - (Y+1) *ClientHeight/2);
{Проводится линия на графике}. LineTo (PX,PY);
end;
Результат работы приложения в этом варианте вы можете видеть на
рис.4.1 б. Как видите, качество графика существенно улучшилось.
Перо может рисовать не только прямые линии, но и фигуры. Полный
список методов канвы, использующих перо, см. во встроенной справке Delphi. А
пока в качестве примера приведем только один из них - Ellipse, который
рисует эллипс или окружность. Он объявлен как
procedure
Ellipse (X1, Y1, Х2, Y2: Integer);
где параметры X1, Х2, Y1, Y2 определяют координаты
прямоугольника, описывающего эллипс или окружность. Например, оператор
. Ellipse (10, 40, 20, 50);
нарисует окружность с диаметром 10 и с координатами центра (15,
45).
Фигуры в общем случае рисуются не пустыми, а закрашенными с
помощью свойства канвы Brush - кисть. Свойство Brush является
объектом, имеющим в свою очередь ряд свойств. Свойство Color определяет
цвет заполнения. Свойство Style определяет шаблон заполнения
(штриховку). По умолчанию значение Style равно bsSolid, что
означает сплошное закрашивание цветом Color.
У пера Pen имеется еще одно свойство, которое мы пока не
рассматривали. Это свойство - Mode (режим). По умолчанию значение Mode
= pmCopy. Это означает, что линии проводятся цветом, заданным в свойстве Color.
Но возможны и другие режимы, в которых учитывается не только цвет Color,
но и цвет соответствующих пикселей фона. Наиболее интересным из этих режимов
является режим pmNotXor - сложение с фоном по инверсному исключающему
ИЛИ. Если задан этот режим, то повторное рисование той же фигуры на том же
месте канвы убирает ранее нарисованное изображение и восстанавливает цвета
пикселей, которые были до первого изображения фигуры.
Эту особенность режима pmNotXor можно использовать для
создания простенькой анимации. Достаточно нарисовать нечто, затем стереть
нарисованное, перерисовать немного измененным - и рисунок будет представляться
ожившим.
Попробуйте сделать сами простенькую мультипликацию - движущуюся
окружность. Начните новое приложение и в раздел implementation вставьте
объявление
X,Y: integer;
Тем самым вы введете глобальные переменные X и Y -
текущие координаты изображения.
В событие формы OnPaint вставьте операторы
. Brush. Color: = clWhite;: = clWhite;. Pen. Mode: = pmNotXor;
Первый из этих операторов задает белый цвет кисти Brush.
Значит ваша окружность будет закрашена внутри белым цветом. Второй оператор
задает белый цвет фона поверхности формы.
Третий оператор устанавливает режим пера pmNotXor, который
позволит вам стирать прежнее изображение прежде, чем нарисовать новое.
Даже самая простая мультипликация нуждается в синхронизации. Иначе
скорость движения будет определяться быстродействием компьютера. Поэтому
перенесите на форму компонент Timer - таймер со страницы System. Этот
компонент описан в разделе 5.7
<mk:@MSITStore:F:\Delphi\100comp.CHM::/5_7.htm>.
Можете посмотреть там его подробное описание. А пока задайте его
свойство Interval равным, например, 30 (это время выдержки в
миллисекундах, но реальное время выдержки будет больше - см. раздел 5.7) и
установите свойство Enabled равным false (это означает, что
таймер не будет запускаться автоматически в момент запуска приложения).
В обработчик события этого компонента OnTimer вставьте
операторы
// Стирание прежнего изображения. Ellipse (Х-5, Y, X+5, Y-1Q);(X);
// Рисование нового изображения. Ellipse (Х-5, Y, X+5, Y-10);
// Останов при достижении конца формы
if (X >=
ClientWidth-20) then. Enabled: = false;
Первый из этих операторов рисует окружность в том месте, где она
была нарисована ранее, т.е. стирает прежнее изображение.
Далее увеличивается на единицу функцией Inc текущая
координата X и изображение окружности рисуется в новой позиции.
Последний оператор останавливает изображение у края формы.
Теперь перенесите на форму кнопку Button и в обработчик
щелчка на ней поместите операторы
Х: =10;: =100;. Ellipse (X-5, Y, X+5, Y-10);. Enabled: =true;
Первые два оператора задают начальные координаты окружности.
Третий оператор рисует окружность в ее начальном положении, а четвертый -
запускает таймер.
Оттранслируйте приложение, запустите его на выполнение, щелкните
на кнопке. Вы увидите изображение окружности, перемещающееся по форме слева
направо. А дальше уж подключите вашу фантазию и преобразуйте это не слишком
интересное приложение во что-нибудь более увлекательное.
На канве можно отображать не только программно создаваемые
изображения, но и изображения, хранящиеся в графических файлах. Только сама
канва не имеет метода загрузки изображения из файла. Поэтому загружать файл
надо в какой-нибудь другой графический объект, способный воспринимать
информацию графических файлов. А затем переписывать изображение из этого объекта
на канву с помощью метода канвы Draw. Его описание:
Draw (X, Y: Integer; Graphic: TGraphic);
Здесь параметры Х и Y определяют координаты левого
верхнего угла размещения изображения на канве, a Graphic - объект,
хранящий информацию. В качестве такого объекта может выступать, например,
объект типа TBitMap, предназначенный для хранения битовых матриц.
Давайте посмотрим, как все это выглядит на практике.
Откройте новое приложение, перенесите на форму компонент OpenPictureDialog
со страницы Dialogs (это компонент диалога открытия графических файлов - см.
раздел 8.2 <mk:@MSITStore:F:\Delphi\100comp.CHM::/8_2.htm>) и кнопку Button.
Разместите OpenPictureDialog в любом месте формы, так как этот компонент
невизуальный, а кнопку разместите внизу формы. В обработчик щелчка на кнопке
занесите код:
procedure
TForm1. Button1Click (Sender: TObject);
var:
TBitMap;
begin
// Выбор пользователем графического файла
if
OpenPictureDialog1. Execute then
begin
// Создание объекта BitMap типа TBitMap: =TBitMap. Create;
// Загрузка в BitMap выбранного графического файла. LoadFromFile (OpenPictureDialog1.
FileName);
// Перенос изображения на канву формы. Draw (10, 10, BitMap);
// Уничтожение объекта BitMap. Free;
end;
end;
Этот код создает временный объект типа TBitMap с именем BitMap.
Затем вызывается диалог открытия графического файла OpenPictureDialog1
и, если пользователь выбрал файл, то он загружается в BitMap методом LoadFromFile.
Затем методом Draw загруженное изображение копируется на канву в
область, с координатами левого верхнего угла (10,10). После этого временный
объект BitMap уничтожается.
Запустите ваше приложение и щелкните на его кнопке. Вы увидите,
что можете загрузить любой графический файл типа. bmp и он отобразится
на канве формы (см. рис.4.2 а). Графические файлы вы можете найти в каталоге
Images. В Delphi 5 и 4 он обычно расположен в каталоге. \program files\Common
Files\Borland Shared. В Delphi 3 он расположен в каталоге. \program
files\Borland\Delphi 3, а в Delphi 1 - в каталоге Delphi 16. В каталоге Images
имеется, в частности, подкаталог \Images\Splash\16Color\, в котором хранится
файл, загруженный в примере рис.4.2
Рис.4.2
Изображение на канве графического файла (а) и его стирание (б) при перекрытии
другим окном
|
а)
|
|
|
б)
|
|
Вы создали неплохое приложение для просмотра графических
файлов. Но теперь давайте попробуем увидеть его крупный недостаток. Не закрывая
своего приложения, перейдите в какую-нибудь другую программу, например,
вернитесь в Delphi. Затем, ничего там не делая, опять перейдите в свое
выполняющееся приложение. Если окно программы, в которую вы уходили, целиком
перекрыло окно вашего приложения, то вернувшись в него вы увидите, что картинка
в окне исчезла. Если же окно вашего приложения перекрывалось только частично,
то вернувшись в свое приложение вы, возможно, увидите результат, подобный
представленному на рис.4.2 б.
Вы видите, что если окно какого-то другого приложения
перекрывает на время окно вашего приложения, то изображение, нарисованное на
канве формы, портится. Посмотрим, как можно устранить этот недостаток.
Если окно было перекрыто и изображение испортилось,
операционная система сообщает приложению, что в окружении что-то изменилось и
что приложение должно предпринять соответствующие действия. Как только
требуется обновление окна, для него генерируется событие OnPaint. В
обработчике этого события (в нашем случае события формы) нужно перерисовать
изображение.
Перерисовка может производиться разными способами в
зависимости от приложения. В нашем примере можно было бы вынести объявление
переменной BitMap (оператор var BitMap: TBitMap) за пределы
приведенной выше процедуры, т.е. сделать эту переменную глобальной, разместив
непосредственно в разделе implementation. Оператор BitMap. Free
можно было бы перенести в обработчик события формы OnDestroy,
происходящего в момент закрытия приложения. Тогда в течение всего времени
выполнения вашего приложения вы будете иметь копию картинки в компоненте BitMap
и вам достаточно ввести в обработчик события OnPaint формы всего один
оператор:
. Draw (10, 10, BitMap);
Сделайте это, и увидите, что изображение на форме не портится
при любых перекрытиях окон.
Помимо рассмотренного метода Draw канва имеет еще
метод копирования CopyRect:
CopyRect (Dest: TRect; Canvas: TCanvas; Source: TRect);
Метод копирует указанную параметром Source область
изображения в канве источника изображения Canvas в указанную параметром Dest
область данной канвы. Тип TRect, характеризующий прямоугольные области Source
и Dest, уже описывался в разделе 3.2
<mk:@MSITStore:F:\Delphi\100comp.CHM::/3_2.htm>.
Например, оператор
. CopyRect (MyRect2, Bitmap. Canvas, MyRect1);
копирует на канву формы в область MyRect2 изображение из
области MyRect1 канвы компонента Bitmap.
Копирование методом CopyRect производится в режиме,
установленном свойством CopyMode. По умолчанию это свойство имеет
значение cmSrcCopy, что означает просто замену изображения,
содержащегося ранее в области Dest, на копируемое изображение. Другие
возможные значения CopyMode позволяют комбинировать изображения, но их
рассмотрение выходит за рамки данной книги.
Этими основными сведениями о выводе графической информации на
канву мы ограничимся. В разделе 3.2
<mk:@MSITStore:F:\Delphi\100comp.CHM::/3_2.htm> были сообщены сведения о
выводе на канву текста. В целом же канва - сложный объект, обладающий еще
многими свойствами и методами. Но это требует развернутого обсуждения,
выходящего за рамки данной книги. В следующей книге серии "Все о
Delphi" эти вопросы будут рассмотрены подробнее.
Оконного компонента, имеющего свойство Canvas - канва.
Компоненты Image и PaintBox
Компоненты Image и PaintBox представляют собой
некоторую ограниченную поверхность с канвой, на которую можно заносить
изображения, как это описано в разделе 4.2
<mk:@MSITStore:F:\Delphi\100comp.CHM::/4_2.htm>. При этом компонент PaintBox,
собственно говоря, не дает ничего нового по сравнению с рисованием на канве
формы. Рисование на PaintBox вместо формы не имеет никаких преимуществ,
кроме, может быть, некоторого облегчения в расположении одного или нескольких
рисунков в площади окна.
Но помимо этих возможностей у компонента Image имеются
свойства, позволяющие работать с различными типами графических
файлов.поддерживает три типа файлов - битовые матрицы, пиктограммы и метафайлы.
Все три типа файлов хранят изображения; различие заключается лишь в способе их
хранения внутри файлов и в средствах доступа к ним. Битовая матрица (файл с
расширением. bmp) отображает цвет каждого пикселя в изображении. При
этом информация хранится таким образом, что любой компьютер может отобразить
изображение с разрешающей способностью и количеством цветов, соответствующими
его конфигурации.
Пиктограммы (файлы с расширением. ico) - это маленькие
битовые матрицы. Они повсеместно используются для обозначения значков
приложений, в быстрых кнопках, в пунктах меню, в различных списках. Способ
хранения изображений в пиктограммах схож с хранением информации в битовых
матрицах, но имеются и различия. В частности, пиктограмму невозможно
масштабировать, она сохраняет тот размер, в котором была создана.
Метафайлы (Metafiles) хранят не последовательность битов, из
которых состоит изображение, а информацию о способе создания картинки. Они
хранят последовательности команд рисования, которые и могут быть повторены при
воссоздании изображения. Это делает такие файлы, как правило, более
компактными, чем битовые матрицы.
Компонент Image позволяет отображать информацию,
содержащуюся в графических файлах всех указанных типов. Для этого служит его
свойство Picture - объект типа TPicture.
Рис.4.3 Окно Picture Editor
|
|
Чтобы познакомиться с этим свойством откройте новое
приложение и перенесите на форму компонент Image. Растяните его или
задайте его свойство Align равным alClient, чтобы он занял всю
клиентскую область формы. Нажмите на кнопку с многоточием около свойства Picture
в окне Инспектора Объектов или просто сделайте двойной щелчок на Image.
Перед вами откроется окно Picture Editor (рис.4.3), позволяющее загрузить в
свойство Picture какой-нибудь графический файл (кнопка Load), а также
сохранить открытый файл под новым именем или в новом каталоге. Щелкните на
Load, чтобы загрузить графический файл. Перед вами откроется окно открытия
графического файла, представленное на рис.4.4 По мере перемещения курсора в
списке по графическим файлам в правом окне отображаются содержащиеся в них
картинки, а над ними - цифры, характеризующие размер картинки. Вы можете
выбрать требуемый вам графический файл любого типа. Напомним, что поставляемые
с Delphi графические файлы вы можете найти в каталоге Images. В Delphi 5 и 4 он
обычно расположен в каталоге. \program files\Common Files\Borland Shared. В
Delphi 3 он расположен в каталоге. \program files\Borland\Delphi 3, а в Delphi
1 - в каталоге Delphi 16. После загрузки файла щелкните на OK в окне Picture
Editor и в вашем компоненте Image отобразится выбранная вами картинка.
Можете запустить ваше приложение и полюбоваться ею. Впрочем, вы и так видите
картинку, даже не выполняя приложение.
Рис.4.4 Окно диалога открытия графического
файла
|
|
|
Когда вы в процессе проектирования загрузили изображение из
файла в компонент Image, он не просто отображает его, но и сохраняет в
приложении. Это дает вам возможность поставлять ваше приложение без отдельного
графического файла. Впрочем, как мы увидим позднее, в Image можно
загружать и внешние графические файлы в процессе выполнения приложения.
Вернемся к рассмотрению свойств компонента Image.
Если установить свойство AutoSize в true, то
размер компонента Image будет автоматически подгоняться под размер
помещенной в него картинки. Если же свойство AutoSize установлено в false,
то изображение может не поместиться в компонент или, наоборот, площадь
компонента может оказаться много больше площади изображения.
Другое свойство - Stretch позволяет подгонять не
компонент под размер рисунка, а рисунок под размер компонента. Установите AutoSize
в false, растяните или сожмите размер компонента Image и
установите Stretch в true. Вы увидите, что рисунок займет всю
площадь компонента, но поскольку вряд ли реально установить размеры Image
точно пропорциональными размеру рисунка, то изображение исказится.
Устанавливать Stretch в true может иметь смысл только для
каких-то узоров, но не для картинок. Свойство Stretch не действует на
изображения пиктограмм, которые не могут изменять своих размеров.
Свойство - Center, установленное в true,
центрирует изображение на площади Image, если размер компонента больше
размера рисунка.
Рассмотрим еще одно свойство - Transparent
(прозрачность). Если Transparent равно true, то изображение в Image
становится прозрачным. Это можно использовать для наложения изображений друг на
друга. Поместите на форму второй компонент Image и загрузите в него
другую картинку. Только постарайтесь взять какую-нибудь мало заполненную,
контурную картинку. Можете, например, взять картинку из числа помещаемых обычно
на кнопки, например, стрелку (файл. \program files\common files\borland
shared\images\buttons\arrow1l. bmp). Передвиньте ваши Image так, чтобы
они перекрывали друг друга, и в верхнем компоненте установите Transparent
равным true. Вы увидите, что верхняя картинка перестала заслонять
нижнюю. Одно из возможных применений этого свойства - наложение на картинку
надписей, выполненных в виде битовой матрицы. Эти надписи можно сделать с
помощью встроенной в Delphi программы Image Editor.
Учтите, что свойство Transparent действует только на
битовые матрицы. При этом прозрачным (т.е. заменяемым на цвет расположенного
под ним изображения) делается по умолчанию цвет левого нижнего пикселя битовой
матрицы.
Мы рассмотрели загрузку изображения из файла в процессе
проектирования. Но свойство Picture позволяет также легко организовать
обмен с графическими файлами любых типов в процессе выполнения приложения. Чтоб
пояснить технику такого обмена, надо сначала подробнее рассмотреть свойство Picture.
Это свойство является объектом, который имеет в свою очередь
подсвойства, указывающие на хранящийся графический объект. Если в Picture
хранится битовая матрица, на нее указывает свойство Picture. Bitmap.
Если хранится пиктограмма, на нее указывает свойство Picture. Icon. На
хранящийся метафайл указывает свойство Picture. Metafile. Наконец, на
графический объект произвольного типа указывает свойство Picture. Graphic.
Объект Picture и его свойства Bitmap, Icon,
Metafile и Graphic имеют методы файлового чтения и записи LoadFromFile
и SaveToFile:
procedure LoadFromFile (const FileName: string);
procedure SaveToFile (const FileName: string);
Для свойств Picture. Bitmap, Picture. Icon и Picture.
Metafile формат файла должен соответствовать классу объекта: битовой
матрице, пиктограмме, метафайлу. При чтении файла в свойство Picture.
Graphiс файл должен иметь формат метафайла. А для самого объекта Picture
методы чтения и записи автоматически подстраиваются под тип файла. Поясним это
на примере.
Давайте построим приложение, аналогичное рассмотренному в разделе
4.2 примеру просмотра графических файлов. Для разнообразия можно организовать
управление им не кнопкой Button, а меню. Поместите на форму компонент Image.
Растяните его или задайте его свойство Align равным alClient,
чтобы он занял всю клиентскую область формы. Перенесите на форму компонент
диалога открытия графического файла OpenPictureDialog (см. раздел 8.2
<mk:@MSITStore:F:\Delphi\100comp.CHM::/8_2.htm>). Поместите также на
форму компонент главного меню MainMenu (см. раздел 6.1
<mk:@MSITStore:F:\Delphi\100comp.CHM::/6_1.htm>) и задайте в нем один
раздел - Файл. В обработчике этого раздела напишите оператор
(OpenPictureDialog1. Execute) then. Picture. LoadFromFile
(. FileName);
Этот оператор вызовет диалог открытия графического файла (см.
рис.4.4) и загрузит в компонент Image1 изображение из выбранного
пользователем файла (см. рис.4.5). Причем файл может быть любого типа: битовая
матрица, пиктограмма или метафайл.
Рис.4.5 Изображение в компоненте Image
битовой матрицы (а) и пиктограммы (6)
|
а)
|
б)
|
|
|
В этом приложении метод LoadFromFile применен к Image1.
Picture. Если будут открываться только файлы битовых матриц, то оператор загрузки
файла можно заменить на
. Picture. Bitmap. LoadFromFile (. FileName);
Для пиктограмм можно было бы использовать оператор. Picture.
Icon. LoadFromFile (. FileName);
а для метафайлов - оператор. Picture. Metafile. LoadFromFile
(. FileName);
или. Picture. Graphic. LoadFromFile (. FileName);
Но во всех этих случаях, если формат файла не совпадет с
предполагаемым, возникнет ошибка. Аналогично работает и метод SaveToFile
с тем отличием, что примененный к Picture или к Picture. Graphic
он сохраняет в файле изображение любого формата. Например, если вы дополните
свое приложение диалогом SavePictureDialog (см. раздел 8.2
<mk:@MSITStore:F:\Delphi\100comp.CHM::/8_2.htm>), введете в меню раздел
Сохранить как и в его обработчик поместите оператор
SavePictureDialog1. Execute then. Picture. SaveToFile
(SavePictureDialog1. FileName);
то пользователь получит возможность сохранить изображение любого
формата в файле с новым именем. Только при этом, чтобы не возникало в
дальнейшем путаницы, расширение сохраняемого файла все-таки должно
соответствовать формату сохраняемого изображения.
Абсолютно идентично для изображений любого формата будет работать
программа, если оператор сохранения вы замените на
. Picture. Graphic. SaveToFile (. FileName);
использующий свойство Picture. Graphic. А если вам известен
формат хранимого в компоненте Image изображения, то вы можете применить
метод SaveToFile к свойствам Picture. Bitmap, Picture. Icon
и Picture. Metafile.
Для всех рассмотренных объектов Picture, Picture. Bitmap,
Picture. Icon и Picture. Metafile определены методы присваивания
значений объектов:
Assign (Source: TPersistent);
Однако, для BitMap, Icon и Metafile
присваивать можно только значения однородных объектов: соответственно битовых
матриц, пиктограмм, метафайлов. При попытке присвоить значения разнородных
объектов генерируется исключение ЕConvertError. Объект Picture -
универсальный, ему можно присваивать значения объектов любых из остальных трех
классов. А значение Picture можно присваивать только тому объекту, тип
которого совпадает с типом объекта, хранящегося в нем.
Метод Assign можно использовать и для обмена изображениями
с буфером Clipboard. Например, оператор
. Assign (Image1. Picture);
занесет в буфер обмена изображение, хранящееся в Image1.
Аналогично оператор
графика delphi изображение приложение
Image1. Picture. Assign (Clipboard);
прочитает в Image1 изображение, находящееся в буфере
обмена. Причем это может быть любое изображение и даже текст.
Надо только не забыть при работе с буфером обмена вставить в
оператор uses вашего модуля ссылку на модуль Clipbrd.
Автоматически Delphi эту ссылку не вставляет.
Возвращаясь к свойствам компонента Image, можно
отметить один недостаток, присущий нашему тестовому приложению, приведенному на
рис.4.5 При загрузке разных изображений размер окна приложения может оказаться
или слишком маленьким, и тогда вы увидите только часть изображения, или слишком
большим, и тогда изображение будет некрасиво размещено в левом верхнем углу
формы, оставляя много пустого пространства. Этот недостаток можно устранить,
если воспользоваться свойствами Height (высота) и Width (ширина)
компонента Image. При свойстве AutoSize установленном в true
размеры Image автоматически устанавливаются равными размерам
загруженного изображения. И этими размерами можно воспользоваться для
соответствующего изменения размеров формы. Например, приведенный ранее код
загрузки изображения из файла можно заменить на следующий:
OpenPictureDialog1. Execute then
begin. Picture. LoadFromFile (. FileName);. ClientHeight:
= Image1. Height+10;. Top: = Form1. ClientRect. Top
+ (Form1. ClientHeight - Image1. Height) div 2;. ClientWidth:
= Image1. Width+10;. Left: = Form1. ClientRect. Left
+ (Form1. ClientWidth - Image1. Width) div 2;
end;
В этом коде размеры клиентской области формы устанавливаются
несколько больше размеров компонента Image1, которые в свою очередь
адаптируются к размеру картинки благодаря свойству AutoSize. Внесите эти
исправления в свое приложение, выполните его и увидите, что форма стала
автоматически адаптироваться к размерам загруженного изображения
Компонент Shape
Компонент Shape только условно может быть отнесен к
средствам отображения графической информации, поскольку просто представляет
собой различные геометрические фигуры, соответствующим образом заштрихованные.
Основное свойство этого компонента - Shape (форма), которое может
принимать значения:
stRectangle
|
прямоугольник
|
stRoundRect
|
прямоугольник
со скругленными углами
|
stEllipse
|
эллипс
|
stSquare
|
квадрат
|
stRoundSquare
|
квадрат со скругленными
углами
|
stCircle
|
Примеры этих форм показаны на рис.4.7
Рис.4.7 Примеры компонента Shape
|
|
Другое существенное свойство компонента - Brush (кисть).
Это свойство является объектом типа TBrush, имеющим ряд подсвойств, в
частности: цвет (Brush. Color) и стиль (Brush. Style) заливки
фигуры. Заливку при некоторых значениях Style вы можете видеть на
рис.4.7 Третье из специфических свойство компонента Shape - Pen
(перо), определяющее стиль линий. Это свойство, как и свойство Brush,
уже рассматривались в разделе 4.2
<mk:@MSITStore:F:\Delphi\100comp.CHM::/4_2.htm>. Справочные данные об
этих свойствах вы можете найти в главе 10*.
* В
книге нет главы 10. Вероятно, автор планировал поместить в этой главе
справочные материалы по рассмотренным в книге объектам Дельфи. - Примечание
разработчика электронной версии.
Компонент Chart
Теперь рассмотрим компонент Chart. Этот компонент позволяет
строить различные диаграммы и графики, которые выглядят очень эффектно
(рис.4.8). Компонент Chart имеет множество свойств, методов, событий,
так что если все их рассматривать, то этому пришлось бы посвятить целую главу.
Поэтому ограничимся рассмотрением только основных характеристик Chart. А
с остальными вы можете ознакомиться во встроенной справке Delphi или просто
опробовать их, экспериментируя с диаграммами.
Рис.4.8 Пример приложения с диаграммами:
начальное состояние (а) и состояние при изменении типа диаграммы и увеличении
фрагмента графика (б)
|
а)
|
|
|
б)
|
|
Компонент Chart является контейнером объектов Series
типа TChartSeries - серий данных, характеризующихся различными стилями
отображения. Каждый компонент может включать несколько серий. Если вы хотите
отображать график, то каждая серия будет соответствовать одной кривой на
графике. Если вы хотите отображать диаграммы, то для некоторых видов диаграмм
можно наложить друг на друга несколько различных серий, для других (например,
для круговых диаграмм) это, вероятно, будет выглядеть некрасиво. Однако, и в
этом случае вы можете задать для одного компонента Chart несколько серий
одинаковых данных с разным типом диаграммы. Тогда, делая в каждый момент
времени активной одну из них, вы можете предоставить пользователю выбор типа диаграммы,
отображающей интересующие его данные.
Разместите один или два (если захотите воспроизвести рис.4.8)
компонента Chart на форме и посмотрите открывшиеся в Инспекторе Объектов
свойства. Приведем пояснения некоторых из них.
AllowPanning
|
Определяет
возможность пользователя прокручивать наблюдаемую часть графика во время
выполнения, нажимая правую кнопку мыши. Возможные значения: pmNone -
прокрутка запрещена, pmHorizontal, pmVertical или pmBoth - разрешена
соответственно прокрутка только в горизонтальном направлении, только в
вертикальном или в обоих направлениях.
|
AllowZoom
|
Позволяет
пользователю изменять во время выполнения масштаб изображения, вырезая
фрагменты диаграммы или графика курсором мыши (на рис.4.8 б внизу показан
момент просмотра фрагмента графика, целиком представленного на рис.4.8 а).
|
Title
|
Определяет
заголовок диаграммы.
|
Foot
|
Определяет
подпись под диаграммой. По умолчанию отсутствует. Текст подписи определяется
подсвойством Text.
|
Frame
|
Определяет
рамку вокруг диаграммы.
|
Legend
|
Легенда
диаграммы - список обозначений.
|
MarginLeft,
MarginRight, MarginTop, MarginBottom
|
Значения
левого, правого, верхнего и нижнего полей.
|
BottomAxis,
LeftAxis, RightAxis
|
Эти свойства
определяют характеристики соответственно нижней, левой и правой осей. Задание
этих свойств имеет смысл для графиков и некоторых типов диаграмм.
|
LeftWall,
BottomWall, BackWall
|
Эти свойства
определяют характеристики соответственно левой, нижней и задней граней
области трехмерного отображения графика (см. рис.4.8 а, нижний график).
|
SeriesList
|
Список серий
данных, отображаемых в компоненте.
|
View3d
|
Разрешает или
запрещает трехмерное отображение диаграммы.
|
View3DOptions
|
Характеристики
трехмерного отображения.
|
Chart3DPercent
|
Масштаб
трехмерности (для рис.4.8 это толщина диаграммы и ширина лент графика).
|
Рядом со многими из перечисленных свойств в Инспекторе
Объектов расположены кнопки с многоточием, которые позволяют вызвать ту или
иную страницу Редактора Диаграмм - многостраничного окна, позволяющего установить
все свойства диаграмм. Вызов Редактора Диаграмм возможен также двойным щелчком
на компоненте Chart или щелчком на нем правой кнопкой мыши и выбором
команды Edit Chart во всплывшем меню.
Если вы хотите попробовать воспроизвести приложение, показанное
на рис.4.8, сделайте двойной щелчок на верхнем компоненте Chart. Вы
попадете в окно Редактора Диаграмм (рис.4.9) на страницу Chart, которая имеет
несколько закладок. Прежде всего вас будет интересовать на ней закладка Series.
Щелкните на кнопке Add - добавить серию. Вы попадете в окно (рис.4.10), в
котором вы можете выбрать тип диаграммы или графика. В данном случае выберите
Pie - круговую диаграмму. Воспользовавшись закладкой Titles вы можете задать
заголовок диаграммы, закладка Legend позволяет задать параметры отображения
легенды диаграммы (списка обозначений) или вообще убрать ее с экрана, закладка
Panel определяет вид панели, на которой отображается диаграмма, закладка 3D
дает вам возможность изменить внешний вид вашей диаграммы: наклон, сдвиг, толщину
и т.д.
Когда вы работаете с Редактором Диаграмм и выбрали тип
диаграммы, в компонентах Chart на вашей форме отображается ее вид с
занесенными в нее условными данными (см. рис.4.11).
Рис.4.9 Редактор Диаграмм, страница Chart,
закладка Series
|
|
Рис.4.10 Выбор типа диаграммы в Редакторе
Диаграмм
|
|
Поэтому вы сразу можете наблюдать результат применения
различных опций к вашему приложению, что очень удобно.
Страница Series, также имеющая ряд закладок, дает вам
возможность выбрать дополнительные характеристики отображения серии. В
частности, для круговой диаграммы на закладке Format полезно включить опцию
Circled Pie, которая обеспечит при любом размере компонента Chart
отображение диаграммы в виде круга. На закладке Marks кнопки группы Style
определяют, что будет написано на ярлычках, относящихся к отдельным сегментам
диаграммы: Value - значение, Percent - проценты, Label - названия данных и т.д.
В примере рис.4.8 включена кнопка Percent, a на закладке General установлен
шаблон процентов, обеспечивающий отображение только целых значений.
Рис.4.11 Форма приложения рис.4.8 с занесенными
в нее условными данными
|
|
Вы можете, если хотите, добавить на этот компонент Chart
еще одну тождественную серию, нажав на закладке Series страницы Chart кнопку
Clone, а затем для этой новой серии нажать кнопку Change (изменить) и выбрать
другой тип диаграммы, например, Bar. Конечно, два разных типа диаграммы на
одном рисунке будут выглядеть плохо. Но вы можете выключить индикатор этой
новой серии на закладке Series, а потом предоставить пользователю выбрать тот
или иной вид отображения диаграммы (ниже будет показано, как это делается).
Выйдите из Редактора Диаграмм, выделите в вашем приложении
нижний компонент Chart и повторите для него задание свойств с помощью
Редактора Диаграмм. В данном случае вам надо будет задать две серии, если
хотите отображать на графике две кривые, и выбрать тип диаграммы Line.
Поскольку речь идет о графиках, вы можете воспользоваться закладками Axis и
Walls для задания координатных характеристик осей и трехмерных граней графика.
На этом проектирование внешнего вида приложения завершается.
Осталось написать код, задающий данные, которые вы хотите отображать. Для
тестового приложения давайте зададим в круговой диаграмме просто некоторые
константные данные, а в графиках - функции синус и косинус.
Для задания отображаемых значений надо использовать методы
серий Series. Остановимся только на трех основных методах.
Метод Clear очищает серию от занесенных ранее данных.
Метод Add:
(Const AValue: Double; Const ALabel: String;: TColor)
позволяет добавить в диаграмму новую точку. Параметр AValue
соответствует добавляемому значению, параметр ALabel - название, которое
будет отображаться на диаграмме и в легенде, AColor - цвет. Параметр ALabel
- не обязательный, его можно задать пустым: ''.
Метод AddXY:(Const AXValue, AYValue: Double;ALabel:
String; AColor: TColor)
позволяет добавить новую точку в график функции. Параметры AXValue
и AYValue соответствуют аргументу и функции. Параметры ALabel и AColor
те же, что и в методе Add.
Таким образом, процедура, обеспечивающая загрузку данных в
нашем примере, может иметь вид:
=155;=251;=203;=404;
var: word;
beginSeries1 do
begin;(A1, 'Цех 1', clYellow);(A2, 'Цех 2',
clBlue);(A3, 'Цех 3', clRed);(A4, 'Цех 4', clPurple);
end;. Clear;. Clear;
for i: =0 to 100 do
begin. AddXY (0.02*Pi*i, sin (0.02*Pi*i), '', clRed);.
AddXY (0.02*Pi*i, cos (0.02*Pi*i), '', clBlue);
end;
end;
Если вы предусмотрели, например, для данных, отображаемых в
диаграмме, две серии Series1 и Series4 разных видов - Pie
и Bar, то можете ввести процедуру, изменяющую по требованию пользователя
тип диаграммы. Эту процедуру можно ввести в событие OnClick какой-нибудь
кнопки, в команду меню или, например, просто в обработку щелчка на компоненте Chart.
Для того, чтобы загрузить данные в Series4 и сделать эту диаграмму в
первый момент невидимой, можно вставить в конце приведенной ранее процедуры
операторы
. Assign (Series1);. Active: =false;
Первый из этих операторов переписывает данные, помещенные в Series1,
в серию Series4. А второй оператор делает невидимой серию Series4.
Смена типа диаграммы осуществляет процедура
. Active: = not Series1. Active;. Active: = not
Series4. Active;
На рис.4.8 б вы можете видеть результат переключения
пользователя на другой вид диаграммы.