Линкфилд
Здесь может быть ваша реклама
|

 Глава 13. Работа с графикой в Kylix

Глава 13. Работа с графикой в Kylix

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

Общий обзор программирования графики в Kylix
Графические компоненты CLX инкапсулируют возможности Qt, которые позволяют достаточно легко добавлять графику в Linux-приложения.
Для рисования в Kylix (так же, как и в Delphi) используется канва объекта, на котором будет производиться рисование.
Канва (холст) - это свойство, имеющееся у некоторых объектов, входящих в CLX Kylix, которое позволяет рисовать на поверхности объекта, как на холсте.

Примечание
Далее по тексту мы будем использовать слово канва вместо слова холст, т. к. это слово более полно описывает поверхность для рисования.

Главное преимущество канвы объекта в том, что она наиболее эффективно использует ресурсы, и вы можете применять одни и те же методы для вывода графики на экран, принтер или графический образ. Канва объекта доступна программисту только во время работы приложения, таким образом, для обращения к канве нужно использовать команды языка Object Pascal.
Способ отображения графики в вашем приложении зависит от типа объекта CLX, канва которого используется для рисования. Если вы напрямую выводите рисунок на канву объекта управления, изображение будет выведено немедленно.
В то же время, если вы рисуете на канве объекта, находящегося вне экрана, Например на канве объекта графического образа TBitmap, изображение не будет отображаться, пока не будет выполнено копирование из графического раза на канву элемента управления.

Примечание
Использование объекта TBitmap в консольных приложениях приведет к исключительной ситуации с выдачей сообщения "Имя проекта: невозможно соединиться с Х-сервером".

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

Обновление экрана
Во время работы приложения многие объекты на экране изменяют свое состояние. Может измениться текст или графика, содержащаяся внутри объекта. Для того чтобы эти изменения отображались на экране, необходимо обновление объектов.
Обновление (refresh) объектов - это процесс, выполняемый операционной системой для перерисовки окон и компонентов, расположенных внутри окон.
Для самостоятельного вызова метода обновления компонента вы можете использовать метод Refresh, который имеется у всех компонентов CLX, поддерживающих обновление.
При обновлении объекта генерируется событие OnPaint. Вы можете написать собственный обработчик события OnPaint. Приведем пример перехвата события обновления формы. Будем выводить окно с текстовым сообщением всякий раз, г когда произойдет обновление формы. Создадим новое приложение - File/New Application. Теперь разместим на форме Form1 кнопку Button1(рис. 13.1).

Рис. 13.1. Форма приложения

Напишем в обработчике события OnPaint формы Form1 следующий код (листинг 13.1):

Листинг 13.1. Код обработки события OnPaint
procedure TForm1.FormPaint(Sender: TObject);
begin
messagedlg('Произошло обновление формы',mtInformation,[mbOK],0);
end;

Теперь напишем код обработки события OnClick.

Листинг 13.2. Код обработки события OnClick
procedure TForm1.ButtonlClick(Sender: TObject);
begin
Form1.Refresh; // Вызываем метод обновления формы
end;

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

Рис. 13.2. Информационное окно, извещающее об обновлении формы

Если вы используете компонент TImage для отображения графики на форме, не нужно будет заботиться об обновлении графического изображения, держащегося в этом компоненте. Обновление будет произведено автоматически. Свойство picture компонента TImage определяет текущий графический образ, рисунок или другую графику, которую отображает компонент.

Типы графических объектов
Kylix предоставляет программисту несколько графических объектов, которые имеют собственные методы для рисования на канве, а также для загрузки и сохранения изображений в графические файлы. В табл. 13.1 приведены основные типы графических объектов CLX.

Таблица 13.1. Типы графических объектов Kylix

ОбъектОписание
PictureИспользуется как контейнер для содержания произвольного графического образа. Для того чтобы объект Picture мог содержать файлы дополнительных графических форматов, используйте метод
Register
BitmapМощный графический объект, который используется для создания, манипулирования (масштабирование, скроллинг, вращение, закраска) и хранения картинок как файлов на диске
Clipboard Представляет собой контейнер, хранящий текст или графические образы, которые могут быть скопированы, вырезаны из приложения или вставлены в него
IconПредставляет собой картинку, загруженную из файла пиктограммы
DrawingСодержит файл, в котором записаны операции, требующиеся для
создания изображения. Не содержит самого изображения. Использование этого объекта позволяет свободно масштабировать изображение без потери деталей и обычно требует меньше памяти, чем хранение графического образа. В то же время, отображает рисунок значительно медленнее, чем другие объекты

Работа с объектом Canvas
С помощью объекта canvas вы можете установить толщину рисуемых линий, тип кисти для закрашивания областей, шрифт для вывода текста, а также массив пикселов для представления графического образа. Все это устанавливается с помощью свойств и методов объекта Canvas.

Свойства и методы объекта Canvas
В табл. 13.2 приводятся наиболее часто используемые свойства объекта Canvas и их описания.

Таблица 13.2. Свойства объекта Canvas

Свойство Описание
FontОпределяет шрифт, который будет использоваться для вывода текста на картинке
BrushОпределяет цвет и образец кисти, которыми будут заполняться графические объекты и фон канвы
РеnОпределяет тип пера канвы, которым будут чертиться линии и геометрические фигуры
PenPos Определяет текущую позицию пера

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

Таблица 13.3. Методы объекта canvas

Метод Описание
ArcПредназначен для черчения дуги эллипса или окружности. В качестве параметров метода передаются координаты четырех точек. Первые две точки (x1, y1) и (х2, у2) определяют диагональ прямоугольника, в который вписан эллипс. Третья точка (хЗ, уЗ) задает начальную точку дуги. Точка (х4, у4) задает конечную точку дуги. Третья и четвертая точки принадлежат прямоугольнику, описывающему эллипс. Точки дуги получаются в результате пересечения прямой, проходящей через центр эллипса и точки (хЗ, уЗ) и (х4, у4}. Дуга рисуется против часовой стрелки от начальной до конечной точки
ChordЧертит замкнутую фигуру, границами которой являются дуга окружности или эллипса и хорда. Параметры, передаваемые в данный метод, аналогичны параметрам метода Arc
CopyRectКопирует прямоугольную часть изображения с одной канвы на другую. Копирование осуществляется в том режиме, который определен свойством CopyMode
DrawРисует изображение, хранящееся в объекте, который определен параметром Graphic, на канву в координаты, задаваемые параметрами х и у. Например,
Image1.Canvas.Draw (5, 24, Image2.Picture.Bitmap);
Копирует в координаты (5, 24) рисунок, находящийся на канве компонента Image2, в канву компонента Image1
DrawFocusRectРисует изображение пунктирного прямоугольника с автоматической установкой режима пера (свойство Mode) в pmXor. Данный метод имеет место лишь в том случае, когда подсвойство DefaultStyle свойства Style приложения установлено в dsWindows
DrawPointОтображает одиночную точку на канве с использованием текущих установок пера
DrawPointsРисует несколько точек с использованием текущих установок пера
EllipseЧертит на канве эллипс или окружность. Параметрами являются две точки (x1, y1) и (х2, у2), которые определяют диагональ прямоугольника, описывающего эллипс
FillRectЗаполняет указанную прямоугольную область канвы цветом, определенным текущим значением свойства кисти (Brush). Например,
Image1.Canvas.FillRect(0, 0, 100, 100);
Заполняет квадрат с главной диагональю, имеющей координаты (0, 0) и (100, 100), цветом, определенным в свойстве color кисти
GetClipRegionВозвращает указатель на текущую вырезаемую область канвы
LineToЧертит на канве прямую линию, начало которой совпадает с текущим значением координат пера (значение свойства PenPos), а конец задается параметром (х, у). Конечная точка не принадлежит линии и не отображается. После чего текущими координатами пера станет точка
(х, у). Например,
Image1.Canvas.LineTo(100, 130);
Чертит линию от текущей позиции пера до точки с координатами (100, 130), не включая саму точку (100, 130), после чего значением PenPos будет точка (100, 130)
MoveToИзменяет текущую позицию пера (значение свойства PenPos) на значение, заданное параметром (х, у). При перемещении пера на канве ничего не чертится. Метод аналогичен прямой установке значения свойства PenPos
PieЧертит замкнутый сегмент эллипса или окружности. Параметры метода аналогичны параметрам метода Arc
PolyBezierЧертит на канве цветом пера Реn сглаженную кривую по заданному множеству точек, определенных в массиве Points. Начинает рисование с точки, определенной параметром startindex, используя следующие две точки как направляющие для изгибов кривой. Кривая заканчивается четвертой точкой массива. Например,
Image1.Canvas.PolyBezier([Point(0, 0), Point (100,10) , Point (20,30) , Point (230, 100)], 0);
Последний параметр, равный нулю,- это параметр Startindex
PolyBezierToТо же самое, что и PolyBezier, только после черчения линии данный метод устанавливает значение свойства PenPos в последнюю точку массива Points
PolygonЧертит на канве многоугольник по заданному множеству точек, определенных в массиве Points, причем первая точка массива соединяется с последней, после чего многоугольник закрашивается цветом, определенным свойством кисти Brush. Например,
Imagel.Canvas.Polygon([Point (0, 0), Point(10,10), Point(20,30), Point (230, 100)]);
PolylineЧертит на канве незамкнутый многоугольник. Аналогичен методу Polygon, только не соединяет первую и последнюю точки массива Points
RectangleЧертит на канве текущим пером Реп прямоугольник, закрашенный цветом, определенным в свойстве кисти Brush. В качестве параметров передаются координаты двух точек: левого верхнего и правого нижнего углов прямоугольника, т. е. его главная диагональ
RoundRectЧертит на канве закрашенный цветом, определенным в свойстве кисти Brush, прямоугольник со скругленными углами. Два параметра (x1, y1) и (х2, у2) задают координаты углов прямоугольника (как в методе Rectangle). Два следующих параметра хЗ и уЗ задают эллипс с шириной хЗ и высотой уЗ точек. Углы прямоугольника скругляются по шаблону данного эллипса
StretchDrawРисует графическое изображение, которое содержится в компоненте, указанном в параметре Graphic, в прямоугольную область канвы, указанную параметром Rect. Причем изображение растягивается или сжимается под размер данной области. Например,
Image1.Canvas.StretchDraw(Rect(0, 0, 29, 29), Image2.Picture.Bitmap);
Уменьшает изображение, имеющее размер больше, чем 30x30 и хранящееся в компоненте Image2, и помещает его на канву компонента Image1
TextHeight Возвращает значение, равное высоте текста, который предполагается вывести на канву с использованием текущего шрифта
TextOutВыводит строку текста, задаваемую параметром Text, на канву в позицию с координатами (х, у). Например,
Image1.Canvas.TextOut(10, 10, 'Kylix - лучшая среда разработки под Linux') ;
TextRectПохож по действию на метод TextOut, только текст, выходящий за пределы определенной прямоугольной области, не выводится
TextWidth Возвращает значение в пикселах, равное длине текста Text, который предполагается вывести на канву компонента текущим шрифтом
TiledDraw Рисует размноженное изображение внутри указанного прямоугольника

Использование пера
Свойство Реn позволяет устанавливать атрибуты пера, которым производится рисование линий и точек, а также других геометрических фигур.
Пepo имеет четыре собственных свойства, которые вы можете изменять:
Color - цвет пера;
Width - ширина пера; s
Style - стиль пера;
Mode - режим пера.
Значения данных свойств определяют способ, которым будут отображаться линий. По умолчанию установлен черный цвет пера и его ширина равна одному пикселу, стиль - сплошной, режим рисования поверх текущего изображения канвы. Рассмотрим последовательно использование этих четырех свойств.

Цвет пера
Вы можете устанавливать цвет пера по своему усмотрению с помощью свойства color во время исполнения приложения. Для этого нужно лишь присвоить соответствующее значение цвета свойству Color пера Реп.
В листинге 13.3 мы устанавливаем красный цвет пера (значение ciRed) по нажатии кнопки Button 1

Листинг 13.3. Установка значения цвета пера
procedure TForm1.ButtonlClick(Sender: TObject);
begin
Canvas.Pen.Color := PenColor.ForegroundColor;
end;

Ширина пера
Ширина пера определяет толщину линий, которыми будут начерчены геометрические фигуры.

Примечание
Если вы создаете кросс-платформенное приложение, которое может функционировать как под Linux, так и под Windows 9х, и ширина пера более одного пиксела, то имейте в виду, что Windows будет всегда рисовать сплошные линии, независимо от значения свойства style пера.

Для смены ширины пера достаточно присвоить необходимое числовое значение свойству width пера (листинг 13.4).

Листинг 13.4. Установка ширины пера
procedure TForml.ButtonlClick(Sender: TObject);
begin
Canvas.Pen.Width := 5;
end;

Стиль пера
Свойство style позволяет вам устанавливать различные стили начертания линий. Это могут быть сплошные линии, пунктирные, точечные и др.
В листинге 13.5 стиль пера меняет последовательно все возможные значения.

Листинг 13.5. Смена стилей пера
procedure TForm1.ButtonlClick (Sender: TObject) ;
begin
with Canvas. Pen do
begin
Style: = psSolid
Style: = psDash
Style: = psDot
Style: = psDashDot
Style: = psDashDotDot
Style: = psClear;
end;
end;

Режим пера
Свойство пера Mode позволяет вам устанавливать различные режимы комбинирования цвета пера с цветом, расположенным на канве. Например, режим постоянного цвета пера, режим инверсии цвета пера или фона канвы и пр.

Установка и определение позиции пера
Текущая позиция рисования, с которой начинается рисование линий, называется позицией пера. Как вы уже знаете, объект канвы хранит текущую позицию пера в свойстве PenPos. Позиция пера нужна только для рисования . Для рисования геометрических фигур и вывода текста на канву вы вызываете необходимые координаты при вызове соответствующих методов. установки нужной позиции пера вызывайте метод MoveTo:

Imagel .Canvas .MoveTo (0, 0);

Данный код установит перо в левый верхний угол канвы.

Примечание
Черчение линий с помощью метода LineTo также устанавливает текущую позицию пера, равную конечной точке линии.

Использование кисти
Свойство Brush канвы позволяет вам указывать, каким образом будет производиться заполнение областей и геометрических фигур.
Кисть имеет три свойства:
Color - цвет кисти;
Style - стиль кисти;
Bitmap - графический образ, который будет применяться для заполнения.
Значения этих свойств определяют способ, которым будут заполняться геометрические фигуры и области канвы. По умолчанию значения установлены следующим образом: цвет кисти - белый, стиль - сплошной, без графического образа для заполнения.
Рассмотрим эти свойства более подробно.

Цвет кисти
Цвет кисти определяет, какой цвет будет использоваться для заполнения внутренних областей геометрических фигур и областей канвы. Для смены цвета кисти достаточно присвоить необходимое значение свойству color кисти.
Цвет кисти используется как фоновый цвет текста и линий. В листинге 13.6 мы устанавливаем синий цвет кисти.

Листинг 13.6. Установка цвета кисти
procedure TForml.ButtonlClick(Sender: TObject);
begin
Canvas.Brush.Color := clBlue;
end;

Стиль кисти
Стиль кисти определяет, каким образом будет заполняться область на канве или геометрическая фигура. Это позволяет программисту комбинировать цвет кисти с уже имеющимися цветами канвы.
Для смены стиля кисти достаточно напрямую установить свойство style в одно из следующих значений:
bsSolid, bsClear, bsHorizontal, bsVertical, bsFDiagonal, bsBDiagonal. bsCross, bsDiagCross, bsDensel, bsDense2, bsDenseS, bsDense4, bsDensc5. bsDense6 ИЛИ bsDense7.
Пример, приведенный в листинге 13.7, показывает, как можно установить стиль кисти. Здесь происходит последовательная установка нескольких значений стиля кисти.

Листинг 13.7. Установка стиля кисти
procedure TForml.ButtonlClick(Sender: TObject);
begin
with Canvas.Brush do
begin
Style:= bsSolid
Style:= bsClear
Style:= bsHorizontal
Style:= bsVertical
Style:= bsFDiagonal
Style:= bsBDiagonal
Style:= bsCross
Style:= bsDiagCross;
end;

Установка значения свойства Bitmap
Свойство Bitmap кисти позволяет указать графический образ, который будет пользоваться для заполнения областей и геометрических фигур, расположенных на канве.
Нижеприведенный пример (листинг 13.8) показывает, как можно загрузить графический образ из файла и присвоить его свойству Bitmap кисти канвы формы Form1.

Листинг 13.8. Загрузка графического образа из файла
var
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
try
Bitmap.LoadFromFile('MyBitmap.bmp');
Forml.Canvas.Brush.Bitmap := Bitmap;
Forml.Canvas.FillRect(Rect(0,0,100,100));
finally
Forml .Canvas. Brush. Bitmap := nil;
Bitmap. Free;
end;
end;

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

Использование методов объекта Canvas
В этой части главы мы рассмотрим методы объекта canvas, которые позволяют рисовать простые графические объекты.

Рисование линий и ломаных
Объект канвы позволяет чертить прямые линии и ломаные линии.
Прямая линия - это точки отрезка прямой, проходящей через две заданные точки.
Ломаная линия - это несколько прямых линий, которые соединены между собой конечными точками.
Для рисования прямой линии на канве вы можете использовать метод LineTo. Данный метод чертит линию из текущей позиции пера в точку, указанную вами, и делает конечную точку линии текущей позицией пера.
Приведенный ниже пример (листинг 13.9) чертит диагональные линии формы каждый раз, когда форма перерисовывается (обновляется). Для этого мы записываем код в обработчик события формы OnPaint.

Листинг 13.9. Пример рисования прямых линий
procedure TForml . FormPaint (Sender : TObject) ;
begin
with Canvas do
begin
MoveTo ( 0 , 0 ) ;
LineTo (ClientWidth, ClientHeight) ;
MoveTo (0, ClientHeight);
LineTo (ClientWidth,
end;
end;

Результат выполнения примера изображен на рис. 13.3.

Рис. 13.3. Форма с диагональными линиями

Для рисования ломаных линий можно воспользоваться специальным методом Polyline.

Параметрами данного метода являются элементы массива Points. Приведем пример рисования ломаной линии:

Forml.Canvas.Polyline([Point(0, 0), Point(12,14), Point(50,30),
Point (130, 120), Point(210,132)]);

Данный пример чертит ломаную линию, состоящую из прямых линий рис. 13.4).

Рис. 13.4. Ломаная линия

Рисование линий с помощью метода Polyline аналогично рисованию нескольких линий с помощью методов MoveTo и ЫпеТо. Ниже приведен пример (листинг 13.10), который строит такую же ломаную, как и предыдущий пример.

Листинг 13.10. Построение ломаной линии
with Canvas do begin
MoveTo (О, О);
LineTo(12, 14);
LineTo(50, 30);
LineTo(130, 120);
LineTo(210,132);
end;

Примечание
Если вы рисуете ломаные линии, то используйте метод Polyline, т. к. он выполняется значительно быстрее, чем вызов нескольких методов LineTo.

Рисование геометрических фигур
Для рисования эллипсов, окружностей или прямоугольников вы можете использовать Методы Ellipse ИЛИ Rectangle соответственно.
Приведем пример (листинг 13.11), в котором рисуется прямоугольник, занимающий левую верхнюю четвертую часть формы, а затем в этот прямоугольник вписывается эллипс (рис. 13.5).

Листинг 13.11. Прямоугольник со вписанным эллипсом
procedure TForml.FormPaint(Sender: TObject);
begin
Canvas.Rectangle(0, 0, ClientWidth div 2, ClientHeight div 2);
Canvas.Ellipse(0, 0, ClientWidth div 2, ClientHeight div 2);
end;

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

Рис. 13.5. Эллипс, вписанный в прямоугольник

Нижеприведенный пример (листинг 13.12) рисует прямоугольник со скругленными углами, которые скруглены по шаблону окружности, с диаметром 10 точек (рис. 13.6).

Листинг 13.12. Прямоугольник со скругленными углами
rocedure TForml.FormPaint (Sender: TObject);
begin
Canvas.RoundRect(0, 0, ClientWidth div 2, ClientHeight div 2, 10, 10);
end;

Рис. 13.6. Прямоугольник со скругленными углами
Для рисования многоугольников с любым количеством углов и сторон вы можете использовать метод Polygon. Метод Polygon содержит в качестве параметров массив точек Points, которые определяют координаты вершин многоугольника. После рисования текущим пером линий многоугольника метод Polygon закрашивает текущим цветом кисти область внутри многоугольника.

Примечание
Данный метод аналогичен методу Polyline, только первая и последняя точки ломаной линии соединяются.

Создание приложения наподобие графического редактора
В графическом редакторе обычно присутствует панель инструментов, на которой располагаются кнопки. Каждая из кнопок позволяет рисовать различные фигуры (линии, точки, геометрические фигуры и многое другое). Такие кнопки удобнее всего создавать с помощью компонента CLX TSpeedButton.
Приложение должно узнавать, какую кнопку нажал пользователь, и переходить в режим рисования данного объекта. Для этого вы можете сопоставить с каждым типом фигуры целое число, но в этом случае вам придется помнить, что обозначает каждое число. Если вы позволите пользователю создавать множество фигур, то это будет довольно трудно.
Однако все это можно значительно упростить, если вы сопоставите имена-константы каждому числу. Кроме того, вы можете прибегнуть к применению перечисляемого типа.
Для объявления перечисляемого типа используйте слово Туре. Например, нижеприведенный код объявляет перечисляемый тип, содержащий все типы фигур, которые приложение позволяет рисовать пользователю:

type
TDrawingTool = (dtLine, dtRectangle, dtEllipse, dtRoundRect) ;

По соглашению, идентификатор типа (в нашем случае - это TDrawingTool) начинается с буквы т, а группа перечисляемых констант начинается с двухбуквенного префикса (в нашем случае - букв dt).
Это объявление эквивалентно объявлению группы констант:

const
dtLine = 0;
dtRectangle = 1;
dtEllipse = 2;
dtRoundRect = 3;

Главное отличие объявления группы констант и перечисляемого типа заключается в том, что в случае объявления типа вы присваиваете константам не только значение, но и новый тип, который позволяет языку Object Pascal проверять соответствие типов и предотвращать возможные ошибки. Переменная, тип TDrawingToo1, может иметь значение только из перечисленных (dtLine ... dtRoundRect). Любая попытка присвоения переменной других чисел (не входящих в диапазон от 0 до 3) вызовет ошибку компиляции.

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

Листинг 13.13. Объявление типа и переменных
type
TDrawingTool = (dtLine, dtRectangle, dtEllipse, dtRoundRect);
TForml = class(TForm)
… { объявление методов }
public
Drawing: Boolean;
Origin, MovePt: TPoint;
DrawingTool: TDrawingTool; { переменная, которая будет содержать текущий
инструмент }
end;

Расположим на панели инструментов четыре кнопки speedButton, каждая из которых будет означать линию, прямоугольник, эллипс или прямоугольник со скругленными углами. Теперь нужно для каждой кнопки написать обработчик события onclick, в котором необходимо присвоить соответствующее значение переменной DrawingTool (листинг 13.14).

Листинг 13.14. Обработчики нажатия кнопок
procedure TForm1.LineButtonClick(Sender: TObject); { Кнопка линии }
begin
DrawingTool := dtLine;
end;

procedure TForml.RectangleButtonClick(Sender: TObject); { Кнопка
прямоугольника }
begin
DrawingTool := dtRectangle;
end;
procedure TForml.EllipseButtonClick(Sender: TObject); { Кнопка эллипса }
begin
DrawingTool := dtEllipse;
end;

procedure TForml.RoundedRectButtonClick(Sender: TObject); { Кнопка
прямоугольника со скругленными углами }
begin
DrawingTool := dtRoundRect;
end;

Теперь нам осталось написать лишь обработчики событий движения мыши (onMouseMove) и отпускания левой кнопки мыши (onMouseup). Эти обработчики представлены в листингах 13.15 и 13.16.

Листинг 13.15. Обработчик события OnMouseup
procedure TForml.FormMouseUp(Sender: TObject; Button TMouseButton; Shift:
TShiftState;
X,Y: Integer);
begin
case DrawingTool of
dtLine:
begin
Canvas.MoveTo(Origin.X, Origin.Y);
Canvas.LineTo(X, Y)
end;
dtRectangle: Canvas.Rectangle(Origin.X, Origin.Y, X, Y);
dtEllipse: Canvas.Ellipse(Origin.X, Origin.Y, X, Y);
dtRoundRect: Canvas.RoundRect(Origin.X, Origin.Y, X, Y, (Origin.X - X) div 2, (Origin.Y - Y) div 2) ;
end;
Drawing := False;
end;

Листинг 13.16. Обработчик события OnMouseMove
procedure TForml.ForniMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if Drawing then
begin
Canvas.Pen.Mode := pmNotXor;
case DrawingTool of
dtLine:
begin
Canvas.MoveTo(Origin.X, Origin.Y);
Canvas.LineTo(MovePt.X, MovePt.Y);
Canvas.MoveTo(Origin.X, Origin.Y);
Canvas.LineTo(X, Y);
end;
dtRectangle:
begin
Canvas.Rectangle(Origin.X, Origin.Y, MovePt.X, MovePt.Y);
Canvas.Rectangle(Origin.X, Origin.Y, X, Y);
end;
dtEllipse:
begin
Canvas.Ellipse(Origin.X, Origin.Y, X, Y);
Canvas.Ellipse(Origin.X, Origin.Y, X, Y);
end;
dtRoundRect:
begin
Canvas.RoundRect(Origin.X, Origin.Y, X, Y,
(Origin.X - X) div 2, (Origin.Y - Y) div 2);
Canvas.RoundRect(Origin.X, Origin.Y, X, Y,
(Origin.X - X) div 2, (Origin.Y - Y) div 2);
end;
end;
MovePt := Point(X, Y);
end;
Canvas.Pen.Mode := pmCopy;
end;

Другие методы работы c графикой в Kylix
Вообще, вам не требуется наличие специальных компонентов для работы с графическими возможностями Kylix. Вы можете создавать, рисовать, сохранять и уничтожать графические объекты без отображения графики на экране. В качестве графического объекта могут выступать bmp-файлы, рисунки, пиктограммы и другие объекты, включая сжатые jpeg-файлы. В большинстве случаев приложение редко рисует напрямую на форме. Обычно сначала создается графический образ, а затем он отображается с помощью компонента CLX image.
Как только вы разместили рисунок в компонент image, вы можете достаточно легко его сохранять, загружать и копировать в буфер обмена.

Примечание
Если вы рисуете не на экране, а, например, на канве объекта TBitmap, изображение не будет отображаться на экране до тех пор, пока не будет произведено копирование рисунка из канвы объекта TBitmap в канву визуального объекта. Более того, необходимо сделать перерисовку визуального объекта после копирования, например с помощью вызова метода Refresh для данного визуального объекта. Если вы рисуете напрямую в канве визуального объекта, таких проблем не возникает.

Иногда картинка превышает размер формы. Для просмотра таких больших изображений можно разместить на форме компонент TScroiiBox и помещать изображение внутрь этого компонента.

Работа с компонентом Image
Компонент image представляет собой контейнер, который может содержать и отображать графический объект.
Вы можете расположить данный компонент в любом месте формы, после чего с помощью инспектора объектов в свойстве Picture указать графический объект, который будет содержаться в компоненте image. Кроме того, данное свойство можно изменять и в процессе выполнения приложения, изменяя свойство Picture.
Если вы хотите, чтобы приложение сразу после запуска создавало чистую заготовку для изображения, вам необходимо выполнить следующие шаги:
1. Создать заготовку обработчика события oncreate для формы, содержащей компонент Image.
2. Создать объект Bitmap и присвоить его свойству Picture.Graphic компонента Image.
В нижеприведенном примере (листинг 13.17) главная форма приложения
Form1 содержит компонент типа TImage, который имеет имя (свойство Name) Image. Код размещен в обработчике события OnCreate формы Form1.

Листинг 13.17. Создание объекта Bitmap
procedure TForml.FormCreate(Sender: TObject);
var
Bitmap: TBitmap; (временная переменная для хранения графического образа;
begin
Bitmap := TBitmap.Create,( создаем графический объект }
Bitmap.Width := 200; { устанавливаем начальную ширину }
Bitmap.Height := 200; { и начальную высоту объекта Bitmap }
Image.Picture.Graphic := Bitmap; { присваиваем созданный графический
объект компоненту Image }
Bitmap.Free; { Нам больше не нужен графический объект, поэтому
уничтожаем его }
end;

Если вы записали вышеприведенный код в обработчике события OnCreate формы Form1 и запустили приложение, то вы сможете увидеть в клиентской части формы белый квадрат, представляющий собой как бы заготовку для изображения. Если вы уменьшите окно таким образом, чтобы изображение (помещалось в нем, автоматически появятся полосы прокрутки.
данной заготовке можно осуществлять любые графические операции. Для этого следует воспользоваться канвой компонента image.
Для работы с линиями объекта Bitmap имеется свойство ScanLine, которое позволяет получать информацию о цветах пикселов одной линии в виде массива RGB.
Пример, приведенный в листинге 13.18, показывает, как можно использовать свойство ScanLine для одновременного получения пикселов одной линии.

Листинг 13.18. Прямая работа с Bitmap
procedure TForml.ButtonlClick(Sender: TObject);
// Данный пример показывает, как можно рисовать напрямую в Bitmap
var
х,у : integer;
Bitmap : TBitmap;
Р : PByteArray;
begin
Bitmap := TBitmap.create;
try
if OpenDialogl.Execute then
begin
Bitmap.LoadFromFile(OpenDialogl.FileName);
for у := 0 to Bitmap.height -1 do
begin
P := Bitmap.ScanLine[y] ;
for x := 0 to Bitmap.width -1 do
Р[х] := у;
end;
end;
canvas.draw(0,0,Bitmap);
finally
Bitmap.free;
end;
end;


Загрузка и сохранение графических файлов
Графические образы, которые используются в приложении, иногда требуется сохранить для дальнейшего использования. Компонент Image позволяет достаточно просто и эффективно загружать графику из файла и сохранять в файл.
Компоненты CLX, которые можно использовать для загрузки, сохранения и других действий с графикой, поддерживают несколько графических форматов: bmp, png, xpms, ico и др.

Загрузка графического образа из файла
Если ваше приложение позволяет изменять готовые изображения или создавать новые, необходимо обеспечить возможность загрузки графики из файла. Для этого можно воспользоваться специальным методом LoadFromFile, который имеется у всех компонентов CLX, способных работать с графикой.
Нижеприведенный пример (листинг 13.19) вызывает диалоговое окно открытия файла и получает из него имя файла, содержащего графический образ. Затем происходит загрузка этого образа в компонент Image1.

Листинг 13.19. Загрузка графики из файла
procedure TForml.OpenlClick(Sender: TObject);
var
CurrentFile: String;
begin
if OpenDialogl.Execute then
begin
CurrentFile := OpenDialogl.FileName;
Imagei.Picture.LoadFromFile(CurrentFile);
end;
end;

Для успешной работы данного примера вам необходимо разместить на форме Form1 компонент openDialog1, который вы найдете на вкладке Dialogs цитры компонентов Kylix, а также меню Menu1 с пунктом Open, и записать, в обработчике события onclick для данного пункта меню этот код.

Сохранение графического образа в файл
Для сохранения графического образа в файл вызовите метод SaveToFiie. Данный метод требует, чтобы вы передали в качестве параметра имя файла, в который будет произведено сохранение графического образа.
Нижеприведенный пример (листинг 13.20) содержит две процедуры для двух пунктов меню Save и SaveAs. Если вызывается пункт меню Save, то пронзятся проверка, был ли уже создан файл для данного графического образа, если он был создан, то образ сохраняется. Если такой файл не был создан, вызывается метод SaveAs, который открывает окно SaveDialogl и запрашивает имя файла для данного графического образа, после чего управление передается методу Save.
Таким образом, для успешной работы данного примера вам необходимо положить на форме Forml меню с двумя пунктами Save и SaveAs и компонент SaveDiaiog с вкладки Dialogs палитры компонентов Kylix. Кроме того, разместите на форме компонент Image1 для хранения графического образа, после чего запишите в обработчик событий нажатия пунктов меню код, приведенный в листинге 13.20.

Листинг 13.20. Сохранение графики в файл
var
Forml: TForml;
CurrentFile:String;
plementation

{$R *.XFM}

rocedure TForml.SavelClick(Sender: TObject);
begin Ef CurrentFile <> '' then
Imagel.Picture.SaveToFiie(CurrentFile) { файл уже существует }
else SaveAslClick(Sender);{ иначе нужно ввести имя файла }
end;

procedure TForml.SaveAslClick(Sender: TObject);
begin
if SaveDialogl.Execute then ( Получить имя файла }
begin
CurrentFile := SaveDialogl.FileName; { сохранить файл с именем,
заданным пользователем }
SavelClick(Sender); { вызов метода сохранения файла }
end;

end;

Работа с буфером обмена
Вы можете использовать системный буфер обмена для копирования и вставки графики внутрь вашего приложения, а также для переноса графики из вашего приложения в другие и из других приложений в ваше. Для этого используется специальный объект Kylix clipboard. Этот объект позволяет оперировать различным типом информации, включая графику и текст.
Прежде чем вы сможете воспользоваться данным объектом, необходимо добавить в блок uses модуля, в котором будет использоваться буфер обмена.
имя модуля OClipbrd:

uses
SysUtils, Types, Classes, Variants, QGraphics, QControls, QForms, QDia-logs, QStdCtrls, OClipbrd;

Данный модуль позволит обращаться к объекту clipboard.

Копирование графики в буфер обмена
Для копирования графической информации в буфер обмена нужно ассоциировать графический объект с объектом clipboard. Это можно сделать с помощью метода Assign.
Код, приведенный в листинге 13.21, показывает, как можно скопировать графический образ, содержащийся в компоненте типа Timage, имеющем имя image, в буфер обмена, выбрав пункт меню Edit/Copy формы Form1.

Листинг 13.21. Копирование графики в буфер обмена
procedure TForml.CopylClick(Sender: TObject);
begin
Clipboard.Assign(Image.Picture)
end.

Вырезание графики в буфер обмена
Вырезание графики в буфер обмена похоже на копирование. Отличие заключается в том, что после копирования картинка, содержащаяся в источнике, уничтожается.
Для реализации данной операции нужно выполнить два последовательных шага:
Скопировать данные в буфер обмена.
Уничтожить оригинальные данные.
В листинге 13.22 показано, как можно осуществить операцию вырезания картинки в буфер обмена. Сначала изображение копируется в буфер обмена, затем место, откуда взято изображение, закрашивается белым цветом с помощью установки режима копирования cmWhiteness.

Листинг 13.22. Вырезание графики в буфер обмена
rocedure TForml.CutlClick(Sender: TObject);
var
ARect: TRect;
begin

 
MKPortal©2003-2008 mkportal.it
MultiBoard ©2007-2009 RusMKPortal