Главная страница ЕЖИдневника


Уроки по Delphi

Урок 6
Внеурочье
Урок 5 Графические часы
Урок 4
Внекласс-1
Урок 3
Урок 2
Урок 1
Урок 0
Уроки по Dephi

Урок 5. Графические часы

Исходных текстов программы здесь ещё нет. Думайте пока сами! %)


Свойство Canvas. Свойства доступные только на этапе выполнения программы. Использование помощи. Создание в проекте новой формы. Тип double. Типизированные константы. Функция Pi. Функция округления и преобразования типа Round. Команды рисования (методы компонента Image). Подключение модулей. Тип TRect.

Delphi позволяет рисовать почти где угодно. Можно рисовать на форме, можно рисовать на метке, можно даже рисовать непосредственно на экране! Но лучше использовать всё-таки специальный компонент TImage, уже хотя бы потому, что этот компонент сам будет следить затем, чтобы при перерисовке окна твоей программы, твои каракули тоже перерисовывались. Если ты нарисуешь что-то, например, на форме, то при сворачивании окна программы твой рисунок сотрётся.

Собственно за рисование отвечает свойство Canvas. Если у компонента есть такое свойство, то на нём можно рисовать, если нет - увы. Кстати, это свойство ты не найдёшь в инспекторе объектов. Это свойство не доступно во время разработки программы. Оно станет доступно только во время исполнения. Разумеется, к нему можно обращаться в тексте программы - ведь текст программы начнёт работать только после запуска. Как же определить есть свойство Canvas у компонента или нет? Если ты выделишь компонент на форме, свойство или событие в инспекторе объекта или поставишь курсор внутрь какого-либо слова в тексте программы и нажмёшь клавишу F1, то откроется система помощи, причём откроется она на описании выделенного объекта, свойства, события или слова (разумеется, если этот элемент в помощи имеется). Если элементу соответствует несколько записей в системе помощи, то тебя поросят выбрать нужный (в Delphi7 очень многим компонентам соответствует по 2 записи - нужно выбирать ту в которой есть аббревиатура VCL). У всех компонентов в помощи имеется ссылка Properties, при нажатии на которую откроется окно со списком всех свойств этого объекта. Тебе останется только найти нужное свойство в этом списке или установить факт его отсутствия.

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

0. С помощью кнопки «New Form» или пункта меню «File/New Form» создаёшь новую форму. Жмёшь на кнопочку «Save». Вводишь какое-нибудь имя для этого нового модуля (конечно можно оставить и Unit2, но лучше использовать осмысленные имена).

1. Помещаешь на новую форму компонент Image (палитра Additional, 6-я кнопка в виде картинки) на форму. Свойство Align выставляешь в alClient, в результате Image будет растекаться по всей форме.

2. Кладёшь на форму Timer. Создаёшь ему обработчик события OnTimer.

3. Объявляешь новые переменные:

var xc,yc : integer;
    u : double;

Обрати внимание. Объявление переменных может занять несколько строк, но слово var пишешь только один раз, то есть var помечает весь блок переменных, а не отдельную его строку. Тип переменных double - это вещественный тип, в нём можно хранить дробные числа. Переменные xc, yc используем для хранения координат центра часов, а в переменную u будем записывать угол поворота стрелок.

4. Объявляешь типизированные константы:

const lh : integer = 60;
      lm : integer = 100;
      ls : integer = 80;

Хотя они и называются константы, в действительности это переменные, только у них с самого начала устанавливаются значения. Значения этих элементов - длина часовой, минутной и секундной стрелок в пикселях. Ну, синтаксис, по-моему, вполне понятен.

5. В теле процедуры пишем:

  xc := Image1.Width div 2;
  yc := Image1.Height div 2;
  u := Pi/2 - Time*2*2*Pi;
  Image1.Canvas.MoveTo(xc,yc);
  Image1.Canvas.LineTo(xc+Round(lh*cos(u)),yc-Round(lh*sin(u)));

В первых двух строчках рассчитываем координаты центра Image, это и будет центр наших часов.

В третьей строчке считаем угол для часовой стрелки. Символ «/» означает деление, символ «*» умножение, «-» знак минус. Порядок действий стандартный для математических выражений, то есть сначала делим/умножаем, потом складываем/вычитаем. Функция Pi возвращает число пи. Объяснять, почему угол считается именно так, надо? Или твоих знаний геометрии хватит? Ах, да, сначала Великая Эроида, затем тяжкое наследие гуманитарного образования… Значит, угол в математике (и в Delphi) принято отсчитывать от горизонтали и против часовой стрелки. А на часах - от вертикали и по часовой. Знак «-» перед Time меняет направление отсчёта, а «пи пополам» смещает начало отсчёта на четверть оборота против часовой стрелки (то есть на цифру 12 на часах). За сутки Time меняет своё значение от 0 до 1, а часовая стрелка должна за это время сделать 2 оборота, то есть «2*2*Pi» радиан. Таким образом, мы получаем угол u в радианах. Именно в радианах этот угол и нужно подставлять в функции синуса и косинуса.

Четвёртая строка: помещаем указатель в центр.

Пятая строка: проводим линию от текущего положения указателя до точки с координатами xc+Round(lh*cos(u)),yc-Round(lh*sin(u)). Координату x получаем, сложив xc и длину стрелки, умноженную на косинус угла. Поскольку косинус угла - величина вещественная, а координаты должны быть целочисленными, нужно использовать функцию Round - округление. Вопрос на засыпку: почему нельзя писать lh*Round(cos(u))? Минус при вычислении координаты y связан с тем, что ось у направлена не вверх (как обычно принято в математике), а вниз, ну для тебя, как специалиста по Бейсику это не должно удивить.

6. Последние три строчки скопируй два раза и модифицируй для отображения минутной и секундной стрелок. Справишься?

7. Теперь нужно подключить эту новую форму к нашей программе. Перейди в Unit1.pas и найди блок, который начинается со слова uses. В этом списке указываются все модули подключённые к твоей программе. В конец этого списка через запятую поставь имя своего нового модуля. При запуске программы будет открываться твоя первая форма, чтобы открыть вторую, нужно дать команду

  Form2.Show;

Подумай, где можно дать эту команду. Кнопочку поставить или на какое событие у формы повесить (например, у формы тоже есть событие OnClick). Важно, что бы это событие вызывалось достаточно редко (один раз или по действию пользователя) - событие OnTimer не подойдёт.

Запусти программу. Часы работают. Только стрелки не стираются. Нужно очищать Image перед каждой новой отрисовкой. Самый простой способ очистить Image - закрасить его весь цветом фона.

1. Объяви новую переменную Rect типа TRect. Этот тип содержит внутри себя 4 поля - left, top, right, bottom целочисленного типа, и предназначен для определения координат прямоугольника.

2. В самом начале тела процедуры нужно присвоить полям Rect значения координат прямоугольника, который мы хотим закрасить и вызвать метод для закраски:

  Rect.Left := 0;
  Rect.Top := 0;
  Rect.Right := Image1.Width-1;
  Rect.Bottom := Image1.Height-1;
  Image1.Canvas.FillRect(Rect);

Домашнее задание. Сделать пункт 6. Сделать стрелки фигурными, а не просто состоящими из одной линии.

На следующем уроке мы сделаем нашим часам циферблат.


Все комментарии (цензурные и по возможности грамотные) рассматриваются в порядке живой очереди, принимаются к сведению и даже публикуются на сайте. Так что если тебе есть что сказать по поводу вышепрочитанного - мыль сюда!!! ;)

пользовательское соглашение, политика конфиденциальности