Как сделать линию в delphi
Delphi site: daily Delphi-news, documentation, articles, review, interview, computer humor.
Вычерчивание прямой линии осуществляет метод LineTo, инструкция вызова которого в общем виде выглядит следующим образом:
Компонент.Canvas.LineTo(х,у) Метод LineTo вычерчивает прямую линию от текущей позиции карандаша в точку с координатами, указанными при вызове метода.
Начальную точку линии можно задать, переместив карандаш в нужную точку графической поверхности. Сделать это можно при помощи метода мо^ето, указав в качестве параметров координаты нового положения карандаша.
Вид линии (цвет, толщина и стиль) определяется значениями свойств объекта Реп графической поверхности, на которой вычерчивается линия.
Довольно часто результаты расчетов удобно представить в виде графика. Для большей информативности и наглядности графики изображают на фоне координатных осей и оцифрованной сетки. В листинге 10.2 приведен текст программы, которая на поверхность формы выводит координатные оси и оцифрованную сетку (рис. 10.4).
Рис. 10.4. Форма приложения Координатная сетка
! Листинг 10.2. Оси координат и оцифрованная сетка
type TForml = class(TForm) procedure FormPaint(Sender: TObject); private < Private declarations >public
var Forml: TForml; implementation
procedure TForml.FormPaint(Sender: TObj ect); var xO,yO:integer; // координаты начала координатных осей
lx,ly:real; // метки (оцифровка) линий сетки по X и Y dlx,dly:real; // шаг меток (оцифровки) линий сетки по X и Y cross:integer; // счетчик неоцифрованных линий сетки
dlx:=0.5; // шаг меток оси X
dly:=l.0; // шаг меток оси Y, метками будут: 1, 2, 3 и т, д.
MoveTo(x0,y0); LineTo(x0,y0^h); // ось X MoveTo(x0,y0); LineTo(xO+w,yO); // ось Y
Начальную точку линии можно задать, переместив карандаш в нужную точку графической поверхности. Сделать это можно при помощи метода MoveTo, указав в качестве параметров координаты нового положения карандаша.
Вид линии (цвет, толщина и стиль) определяется значениями свойств объекта Реп графической поверхности, на которой вычерчивается линия.
Довольно часто результаты расчетов удобно представить в виде графика. Для большей информативности и наглядности графики изображают на фоне координатных осей и оцифрованной сетки. В листинге 10.2 приведен текст программы, которая на поверхность формы выводит координатные оси и оцифрованную сетку (рис. 10.4).
Рис. 10.4. Форма приложения Координатная сетка
Листинг 10.2. Оси координат и оцифрованная сетка
unit grid_;
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, StdCtrls;
procedure FormPaint(Sender: TObject);
Form1: TForm1; implementation
procedure TForm1.FormPaint(Sender: TObject);
x0,y0:integer; // координаты начала координатных осей
dx,dy:integer; // шаг координатной сетки (в пикселах)
h,w:integer; // высота и ширина области вывода координатной сетки
lx,ly:real; // метки (оцифровка) линий сетки по X и Y
dlx,dly:real; // шаг меток (оцифровки) линий сетки по X и Y
cross:integer; // счетчик неоцифрованных линий сетки
dcross:integer;// количество неоцифрованных линий между оцифрованными
х0:=30; у0:=220; // оси начинаются в точке (40,250)
dx:=40; dy:=40; // шар координатной сетки 40 пикселов
dcross:=1; // помечать линии сетки X: 1 — каждую;
dlx:=0.5; // шаг меток оси X
dly:=1.0; // шаг меток оси Y, метками будут: 1, 2, 3 и т. д.
with forml.Canvas do begin
MoveTo(x0,v0); LineTo(x0,y0-h); // ось X
MoveTo(x0,y0); LineTo(x0+w, y0); // ось Y
// засечки, сетка и оцифровка по оси X
if cross = 0 then // оцифровка
MoveTo(x,y0-3);LineTo(x,y0-h); // линия сетки
// засечки, сетка и оцифровка по оси Y
MoveTo(х0+3,у); LineTo(x0+w,у); // линия сетки
ly:=ly+dly; until (y
Особенность приведенной программы заключается в том, что она позволяет задавать шаг сетки и оцифровку. Кроме того, программа дает возможность оцифровывать не каждую линию сетки оси х, а через одну, две, три и т. д. Сделано это для того, чтобы предотвратить возможные наложения изображений чисел оцифровки друг на друга в случае, если эти числа состоят из нескольких цифр.
Знаете ли Вы, что, как не тужатся релятивисты, CMB (космическое микроволновое излучение) - прямое доказательство существования эфира, системы абсолютного отсчета в космосе, и, следовательно, опровержение Пуанкаре-эйнштейновского релятивизма, утверждающего, что все ИСО равноправны, а эфира нет. Это фоновое излучение пространства имеет свою абсолютную систему отсчета, а значит никакого релятивизма быть не может. Подробнее читайте в FAQ по эфирной физике.
Хотелось бы обратить ваше внимание на то что начало координат находится в левой верхней точке, а не в левой нижней как многие привыкли.
При помощи Canvas построим прямую.
Для начала кинем на форму кнопку (Button) и четыре Edit'a, для ввода координат начальной и конечной точки прямой(x1,y1,x2,y2).
В var пропишем
x1,x2,y1,y2:integer;
Два раза кликаем на кнопку и в процедуре пишем
Эта команда устанавливает положение "кисти" в координаты заданные в Edit1 и Edit2 и передаваться в переменные X1 и Y1 соответственно. Команда strtoint переводит строковую переменную в целое число.
Здесь мы указываем координаты конца линии. Они будут забираться из Edit3 и Edit4 и передаваться в переменные X2 и Y2 соответственно.
Зато у него есть DC. Это практически то же самое.
На форме лежал фрейм. Откуда же взялся TImage?
> вертикальную линию, например, я не могу провести
> до нижнего конца формы(появляется "мертвая зона").
Если линия рисуется на канве TImage, то, естественно, только в пределах TImage она и может рисоваться. Что тут странного?
> TPanel работает нормально, но у него нет Canvas.
1. На форме лежал фрейм. Потом откуда-то же взялся TImage. Потом откуда-то взялась еще и панель. Остается только догадываться, что же Вам все-таки нужно получить.
2. У панели есть Canvas, но он в protected. Получить к нему доступ можно так:
type
TFriendPanel = class(TPanel);
.
with TFriendPanel(Panel1).Canvas do .
> Поделитесь идеями рисования.
Интересный эффект
Self.Canvas.LineTo прорисовывает до конца, а
Image1.Canvas.LineTo нет.
Зависит от первоначального размера окна.
Размер Image1 изменяется нормально.
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
Image1: TImage;
Label1: TLabel;
procedure FormResize(Sender: TObject);
private
< Private declarations >
public
< Public declarations >
end;
var
Form1: TForm1;
procedure TForm1.FormResize(Sender: TObject);
begin
Image1.Top:=0;
Image1.Height:=Image1.Parent.Height;
Image1.Canvas.Brush:=Image1.Parent.Brush;
Image1.Canvas.FillRect(Image1.ClientRect);
Image1.Canvas.MoveTo(0,0);
Image1.Canvas.LineTo(0,Image1.Height-5);
Image1.Canvas.MoveTo(0,Image1.Height-5);
Image1.Canvas.LineTo(Image1.Width,Image1.Height-5);
Label1.Caption:=format("Image1 Width=%d Height=%d",[Image1.Width,Image1.Height]);
Self.Canvas.FillRect(Self.ClientRect);
Self.Canvas.MoveTo(Panel1.Width+10,0);
Self.Canvas.LineTo(Panel1.Width+10,Self.ClientRect.Bottom-10);
Self.Canvas.MoveTo(Panel1.Width+10,ClientRect.Bottom-10);
Self.Canvas.LineTo(Self.Width,ClientRect.Bottom-10);
end;
> Для того, чтобы нарисовать линию на фрейм кладу TImage.
Вместо того, чтобы посмотреть справку или хотя бы просто в Инспектор Объектов.
> Интересный эффект
> Self.Canvas.LineTo прорисовывает до конца,
> а Image1.Canvas.LineTo нет.
> Зависит от первоначального размера окна.
Если рисовать в OnResize (. ) - то еще как зависит.
> Размер Image1 изменяется нормально.
Ну, хоть это хорошо.
Все выбрасываем в помойку, пишем обработчик OnPaint и в нем рисуем все, что угодно на канве самой формы.
И не имеем никаких проблем.
Причем тут фрейм вообще?
Что за дурь ты пишешь?
Изменю формулировку вопроса.
Как соединить два объекта, находящихся во фрейме, вертикальной линией. Связь не должна разрываться при изменении размеров фрейма.
Интересно, как провести линию на фрайме. Пример.
> Как соединить два объекта, находящихся во фрейме,
> вертикальной линией. Связь не должна разрываться при
> изменении размеров фрейма.
Вот с ЭТОГО и надо было начинать. Теперь задача понятна.
type
TFrame1 = class(TFrame)
Edit1: TEdit;
Edit2: TEdit;
private
FCanvas: TCanvas;
FOnPaint: TNotifyEvent;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
protected
procedure DoPaint; dynamic;
procedure Resize; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Canvas: TCanvas read FCanvas;
property OnPaint: TNotifyEvent read FOnPaint write FOnPaint;
end;
constructor TFrame1.Create(AOwner: TComponent);
begin
inherited;
FCanvas := TControlCanvas.Create;
TControlCanvas(FCanvas).Control := Self;
Edit1.Align := alTop;
Edit2.Align := alBottom
end;
destructor TFrame1.Destroy;
begin
FCanvas.Free;
inherited
end;
procedure TFrame1.DoPaint;
begin
if Assigned(FOnPaint) then
FOnPaint(Self)
end;
procedure TFrame1.WMPaint(var Message: TWMPaint);
begin
inherited;
DoPaint
end;
procedure TFrame1.Resize;
begin
inherited;
Invalidate
end;
Мы ввели в класс фрейма канву и событие OnPaint, а кроме того заставили его перерисовываться при изменении размеров. Теперь можем все это спокойно использовать где и как угодно. Например:
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
FFrame: TFrame1;
procedure FramePaint(Sender: TObject);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FFrame := TFrame1.Create(Self);
with FFrame do
begin
OnPaint := FramePaint;
Parent := Self;
Align := alClient
end
end;
Читайте также: