Здавалка
Главная | Обратная связь

Задания для самостоятельного выполнения

Begin

if ssleft in shift

then image1.Canvas.LineTo(x,y);

end;

2. Запустите проект и попробуйте перемещать мышь с нажатой левой кнопкой. За мышкой останется след. Отпустите кнопку — и рисование прекратится. Но стоит снова нажать левую кнопку мыши, как нарисованная кривая соединяется прямой линией с курсором мыши.

Понятно, как исправить ошибку: нужно в момент нажатия кнопки "перескакивать" в новое положение курсора без рисования.

3. Сделаем это в обработчике события OnMouseDown:

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

Begin

image1.Canvas.MoveTo(x,y);

end;

Теперь перейдем к закрашиванию. Класс Canvas содержит процедуру FloodFill , которая может работать в двух вариантах: или закрашивать область текущим цветом до границы заданного цвета, или перекрашивать точки заданного цвета до границы любого другого цвета (в этом случае граница может состоять даже из частей разного цвета!). Различаютсяэти варианты значением последнего параметра процедуры — fsBorder или fsSurface. Например, чтобы закрасить красным область с границей черного цвета:

Canvas.Brush.Color:=clRed;

Canvas.FloodFill(X,Y, clBlack, fsBorder);

Перекрасить красную область в синий цвет:

Canvas.Brush.Color:=clBlue;

FloodFill(X,Y, clRed, fsSurface);

Обычно мы не знаем заранее, какого цвета область, которую мы собираемся перекрашивать. Но это легко можно определить с помощью свойства Pixels, в котором хранятся цвета всех точек изображения. Pixels [X,Y] и есть цвет точки канвы с координатами X, Y.

4. Завершим создание редактора. Поместим на форму компонент TColorGrid(страница Samples). При изменении компонента будем изменять и цвет закрашивания:

procedure TForm1.ColorGrid1Change(Sender: TObject);

Begin

image1.Canvas.Brush.Color:=colorgrid1.BackgroundColor;

end;

5. Перепишем теперь обработчик события OnMouseDown:

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

Begin

with Image1.Canvas do

case Button of

mbLeft: MoveTo(X,Y);

mbRight: FloodFill(X,Y, Pixels[X,Y],fsSurface);

end;

end;

6. Внесем теперь некоторые усовершенствования. Во-первых, с помощью компонента TColorGrid мы: можем изменять и цвет линии. Для этого достаточно в обработчик события OnChange добавить строки:

Image1.Canvas.Pen.Color:=ColorGrid1.ForegroundColor;

Image1.Canvas.Brush.Color:=ColorGrid1.BackgroundColor;

 

7. Во-вторых, можем изменять толщину линии. Используем для этого компонент TSpinEdit, расположенный на вкладке Samples. TSpinEdit представляет собой поле ввода, воспринимающее только числовые значения, и стрелки вверх и вниз, с помощью которых пользователь может "прокручивать" в заданных пределах (свойства MinValue и MaxValue) значения в поле ввода. Заметим, что границы, установленные для изменения значения TSpinEdit, можно нарушать при вводе данных с клавиатуры. Если же на этапе выполнения программы стереть содержимое поля ввода, то возникнет ошибка преобразования пустого значения в число. Для предотвращения этих неприятностей можно запретить редактирование с клавиатуры значения поля ввода (свойство EditorEnabled установить в False),

Напишем обработчик события OnChange для объекта SpinEditl:

procedureTForml.SpinEditlChange (Sender: TObject);

Begin

Imagel.Canvas.Pen.Width:=SpinEditl.Value;

end;

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

procedure TForm1.FormCreate(Sender: TObject);

Begin

Image1.Canvas.FillRect(BoundsRect);

end;

9*.Дополнить проект меню с пунктами "Открыть рисунок" и "Сохранить рисунок" для работы с графическими файлами.

Задания для самостоятельного выполнения

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

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

Комментарий. Процедура обработки нажатия кнопки содержит операторы:

Edit2.Text :=Edit1.Text:

Edit1.Text:='';

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

Задание 3. Поместить на форму два поля ввода и кнопку "Обменять". При нажатии на кнопку текст из первого поля ввода переписывается во второе, а из второго в первое.

Комментарий. Если будете использовать переменную не забудьте ее описать.

Задание 4. Поместить на форму два поля ввода и кнопку со стрелкой " » ". При нажатии на кнопку текст из левого поля ввода переписывается в правое, при этом стрелка на кнопке изменяет свое направление. Если теперь нажать кнопку еще раз, то текст из правого поля перепишется в левое, а стрелка снова изменит свое направление.

Задание 5. Поместить на форму панель, два поля ввода и кнопку "Объединить". При нажатии на кнопку текст из первого поля ввода через пробел объединяется с текстом из второго поля и выводится на панель.

Задание 6. Поместить на форму панель без текста. При движении мышки над панелью на ней появляется текст "Ой, шекотно!". При уводе мышки с панели текст исчезает.

Комментарий. Нужно написать обработчик события OnMouseMove для панели и аналогичный обработчик для самой формы.

Задание 7. Поместить на форму панель и кнопку "Счетчик нажатий". При запуске программы на панели находится нулевое значение. При каждом нажатии на кнопку значение счетчика увеличивается на единицу.

Комментарий. Первый вопрос, на который нужно ответить перед написанием кода: "Где хранить значение счетчика?". Можно воспользоваться свойством Tag для кнопки Button1 (или панели Panel1):

procedure TForml.ButtonlClick (Sender : TObject);

var S: string;

Begin

with Buttonl do begin

Tag:=Tag+l;

Panell.Caption:=IntToStr(Tag);

end;

end;

IntToStr — функция, которая возвращает символьное представление целого числа. Она удобнее, чем процедура Str, которая имеется в языке Pascal.

Начальное значение переменной Tag равно нулю, однако если мы при разработке формы не установим правильно свойство Panel1.Caption, то при запуске программы символ "0" на панели не появится. При желании можно задать свойство Panel1.Caption и позже — на этапе создания формы приложения (событие OnCreate). Напишем обработчик этого события:

procedure TForml.FormCreate(Sender: TObject);

Begin

Panel1.Caption:=IntToStr(Button1.Tag);

end;

В этом случае вся необходимая информация содержится в одном месте, что облегчает модификацию проекта.

Задание 8. Добавьте к предыдущему проекту кнопку "Сброс", которая устанавливает значение счетчика в начальное состояние.

Комментарий. Если начальное состояние известно заранее (например, нулевое значение), то обработчик для кнопки "Сброс" пишется легко:

procedure TForml.Button2Click(Sender : TObject);

Begin

Button1.Tag:=0;

Panel1.Caption:=’0’;

end;

Однако если мы заранее не устанавливаем начальное значение, а берем его из свойства Tag, то возникает проблема: где хранить это значение? Используем для этого вспомогательную переменную start. Ее можно разместить в описании класса TForm1 в разделах private или public или непосредственно в разделе var модуля Unit1. Инициализируем значение переменной start: =Button1.Tag; в самом начале работы программы - в процедуре TForm1. FormCreate, а используем — в обработчике для кнопки "Сброс":

procedure TForm1.Button2Click(Sender: TObject);

Begin

with Button1 do begin

Tag:=start;

Panel1.Caption:=IntToStr (Tag) ;

end;

end;

Задание 9. Поместить на форму панель с текстом и две кнопки: "Показать" и "Спрятать". При нажатии на кнопку ку "Спрятать" текст на панели исчезает, при нажатии на кнопку "Показать" - появляется.

Задание 10. Поместить на форму панель с текстом и одну кнопку. Вначале на кнопке написано "Спрятать". Пру нажатии на кнопку текст на панели исчезает, а на самой— кнопке появляется слово "Показать". Теперь уже при нажатии на кнопку текст появляется на панели, а на кнопке появляется слово "Спрятать".

Комментарий. Начальное значение свойства Panel1.Caption можно запомнить глобальной переменной stxt при создании формы. Остальное делается в обработчике нажатия кнопки.

Задание 11.Поместить на форму панель с двумя кнопками: «Влево» и «Вправо». При нажатии на кнопку «Влево» вся панель перемещается по форме влево (если это возможно). При нажатии на кнопку "Вправо" вся панель перемещается по форме вправо (если это возможно.

Комментарий. Движение панели легко обеспечивается следующей строкой в обработчике события кнопки «Влево»:

with Panel1 do if Left>=10 then Left:=Left-10;

Более внимательно следует отнестись к написанию обработчика для кнопки "Вправо": следует учитывать ширину рабочей области формы (свойство ClientWidth), а не ширину всей формы (свойство Width):

with Panel1 do

if Left+Width<=Form1.ClientWidth-10 then Left:=Left+10;

Задание 12. Поместить на форму панель с двумя кнопками: "Вверх ' и "Вниз". При нажатии на кнопку "Вверх" вся панель перемещается по форме вверх (если это возможно).

При нажатии на кнопку "Вниз" вся панель перемещается по форме вниз (если это возможно).

Задание 13. Поместить на форму кнопку с надписью "Сменить место". При нажатии на кнопку ее положение на форме меняется случайным образом, при этом кнопка не должна даже частично уходить за границу формы.

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

Комментарий. В обработчик события OnMouseMove поместим оператор

Caption : = ' ( ' +IntToStr (X) + ' ; ' +IntToStr (Y) + ') ' ;

Задание 15.Поместить на форму прямоугольник (экземпляр класса TShape — фигура). При щелчке мышью на прямоугольнике его i:.!ier изменяется случайным образом.

Комментарий. Среди событий на которые реагирует объект типа TShape нет события OnClick поэтому используем событие OnMouseDown. Для изменения цвета фигуры в обработчике этого события изменим цвет кисти, которой закрашивается фигура:

Shape1 .Brush. Color:=RGB(random(256), random(256), random(256));

 

Задание 16. Поместить на форму круг и три кнопки с надписями "Красный", "Желтый', "Зеленый". При нажатии на любую из них цвет круга изменяется в соответствии с надписью на выбранной кнопке.

Задание 17. Поместить на форму фигуру и две кнопки - "Круг" и "Квадрат". При нажатии на кнопку "Круг" фигура становится кругом, при нажатии на кнопку "Квадрат" фигура становится квадратом.

Задание 18. Поместить на форму круг и две кнопки с надписями «Увеличить» и «Уменьшить». Нажатие на первую кнопку приводит к увеличению радиуса круга, нажатие на вторую к уменьшению радиуса. Положение центра круга на форме этом не должно изменяться.

Задание 19. Поместить на форму фигуру. При щелчке мышкой в произвольном месте формы фигура совмещается с курсором мыши.

Комментарий. (Для реализации проекта необходимо написать обработчик события FormMouseDown для формы:

if X<=ClientWidth-Shape1.Width then

Shape1.Left:=X;

if Y<=ClientHeight-Shape1.Height then

Shape1.Top:=Y;

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

Дело в том, что Shape1 "перехватывает" щелчок мышки, а обработчик события OnMouseDown для Shape1 не написан — вот ничего и не происходит. В следующем проекте будет показано, как решить эту проблему.

Задание 20. Поместить на форму фигуру (экземпляр класса TShape). При движении мышки в пределах рабочей области формы фигура "подбегает" к курсору мыши.

Комментарий. Обработчик события OnMouseMove, по сути дела, совпадает с обработчиком OnMouseDown из предыдущего проекта:

if X<=ClientWidth-Shape1.Width then

Shape1.Left:=X;

if Y<=ClientHeight-Shape1.Height then

Shape1. Top:=Y,

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

Чтобы исправить этот недостаток, напишем обработчик события и для Shape1. Но поскольку необходимые действия уже реализованы в процедуре FormMouseMove,, вызовем ее. При этом учтем, что передаваемые в процедуру значения X, Y являются локальными координатами точки фигуры, а не точки формы, то есть отсчитываются не от верхнего левого угла рабочей области формы, а от верхнего левого угла фигуры.

procedure TForm1.ShapelMouseMove

(Sender: TObject; Shift: TShiftState; X, Y: integer) ;

Begin

FormMouseMove(Sender, Shift,

Shape1.Left+x, Shape1.Top+Y);

end;

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

Комментарий. Точка, находящаяся "на полпути" между верхним левым углом фигуры и курсором мыши, имеет координаты

newX = (Shape1.Left + CurX) div 2

newY = (Shape1.Top + CurY) div 2

где curX, curY — координаты курсора мыши при срабатывании таймера. Но в обработчике события OnTimer мы не можем получить доступ к координатам мыши, а в обработчике события OnMouseMove не можем получить доступ к таймеру. Организовать взаимодействие между обработчиками можно через общие (или глобальные) переменные. Добавим, например, в описании класса TForm1 переменные CurX,CurY:

TForm1 = class(TForm)

Shape1: TShape;

Timer1: TTimer;

procedure FormMouseMove(Sender: TObject;

Shift: TShiftState; X, Y: integer);

procedure Timer1Timer(Sender: TObject); private

{ Private declarations }

CurX, CurY: integer;

public

{ Public declarations } end;

Поскольку переменные добавлены в раздел private, они будут доступны только внутри данного модуля, но для данного проекта это непринципиально. Эти переменные должны "отслеживать" изменение координат курсора мыши, поэтому поместим операторы CurX: =X; CurY : =Y; в процедуру FormMouseMove.

Теперь этими переменными можно пользоваться при срабатываниях таймера:

procedure TForml.Timer1Timer(Sender: TObject);

var newX, newY:integer;

Begin

newX:=(Shape1.Left+CurX) div2;

newY:=(Shape1.Top+CurY) div 2;

if newX<=ClientWidth-Shape1 .Width

then Shape1.Left:=newX;

if newY<=ClientHeight-Shape1.Height

then Shape1.Top:=newY;

end;

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

Комментарий. Достаточно написать процедуру обработки срабатывания таймера

procedure TForm1.Timer1Timer(Sender: TObject);

Begin

Shape1.Brush.Color:=RGB(random(255),random(255),random(255));

end;

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

Комментарий. Зададим в Инспекторе объектов начальный цвет фигуры (свойство Shape, Brush, Color) красным. Понятно, что новый цвет однозначно определяется текущим цветом фигуры.

Попробуйте следующий вариант ошибочен:

procedure TForm1.Timer1Timer(Sender: TObject);

Begin

with Shape1.Brush do begin

if Color= clRed then Color:=clYellow;

if Color= clYellow then Color:=clGreen;

if Color= clGreen then Color:=clRed;

end;

end;

 

Поясните – почему он ошибочен и исправьте ошибку.

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

Задание 25. Дополнить предыдущий проект таким образом, чтобы зеленый цвет "горел" в два раза дольше, чем красный, а красный — в два раза дольше, чем желтый.

Задание 26. Проект "Светофор". Разместить на панели три круга (класс TShape), которые будут "зажигаться" по принципу светофора через равные промежутки времени. В качестве нейтрального выберите серый цвет.

Комментарий. От других проект отличается наличием трех фигур. И в этом случае для организации циклической последовательности цветов используем свойство Tag, но уже для панели, содержащей все три круга. Для упрощения логики алгоритма при каждом срабатывании таймера можно сначала сделать серыми все круги. а затем "зажечь" нужный.

procedure TForm1.TimerlTimer(Sender: T0bject;

Begin

Shape1.Brush.Color:=clGray;

Shape2;Brush.Color:=clGray;

Shape3.Brush.Color:=clGray;

with Panel1 do begin

case Tag of

0,2:Shape2.Brush.Color:=clYellow;

1:Shape3.Brush.Color:=clGreen;

3:Shape1.Brush.Color:=clRed;

end;

Tag:=(Tag+1) mod 4;

end;

end;

 

Задание 27. Поместить на форму кнопку с символом "0". При нажатии на кнопку надпись на ней "работает" как счетчик числа нажатий.

Комментарий. Приведем основу решения — обработчик события OnClick:

procedure TForml.ButtonlClick(Sender: TObject);

Begin

with Button1 do begin

Tag:= Tag+1;

Caption:= IntToStr(Tag);

end;

end;

Начальное значение свойства Tag равно нулю по умолчанию.

Задание 28. Проект "Секундомер". Выведите на форму надпись, на которой будет отображаться число секунд, прошедших с момента запуска программы.

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

procedure :TForm1:Timer1Timer (Sender : TObject);

Begin

with Timer1 do begin

Tage:=Tag+1;

Label1.Caption:=IntToStr(Tag);

End;

End;

Задание 29. Измените предыдущий проект так, чтобы выводить время с десятыми долями секунды.

Комментарий. Дляперевода вещественных чисел в символьное представление в Delphi существуют функции FloatToStr и FloatToStrF.

Функция FloatToStr сама определяет формат вывода, поэтому ее проще использовать, но мы не можем влиять на результат ее применения. Заменим, например, в предыдущем проекте строку

Label1.Caption := FloatToStr (Tag/10);

не изменяя (для наглядности) интервал срабатывания таймера (конечно, для получения реального секундомера его следует уменьшить в 10 раз). Тогда мы увидим, что целые значения выводятся без нуля десятых, что явно не соответствует нашему замыслу.

Функция FloatToStrF имеет дополнительные параметры, которые определяют формат вывода вещественных чисел:

Value - выводимое значение;

Format - формат вывода;

Precision - число значащих цифр;

Digits - число цифр после запятой.

Для нашего проекта самым подходящим является формат вывода ffFixed. Но и он имеет свои особенности.

Для примера покажем, в каком виде выведется число 345,19 при различных значениях параметров:

FloatToStrF(345.19, ffFixed, 4, 1) -результат 345,2

FloatToStrF(345.19, ffFixed, 4, 2) -результат 345,20

FloatToStrF(345.19, ffFixed, 5, 2) -результат 345,19

FloatToStrF(345.19, ffFixed, 3, 3) -результат 345,000

FloatToStrF(345.19, ffFixed, 2, 2) -результат 3,5E2

При выводе происходит округление результата в соответствии с заданным значением параметра Digits. Но при этом учитывается и количество значащих цифр числа. В случае, если значение параметра Precision меньше, чем количество цифр в целой части числа, результат выводится в экспоненциальной форме.

Переменная, в которой будет храниться текущее время, должна быть вещественной. Поэтому заведем вспомогательную переменную Time и будем вычислять ее при каждом срабатывании таймера. Для большей общности при вычислении времени будем использовать свойство таймера Interval:

procedure TForm1.Time.Sender: TObject);

begin

Time:=Time + Timer1.Interval/10;

Label1.Caption:=FloatToStr(Time,ffFixed, 6,1);

end;

Инициализацию переменной Time можно выполнить в разделе констант:

const Time: real = 0.0;





©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.