(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Графические часы (исходники, документация)

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);

Вопросы и ответы

В. Вроде часы со стрелочками у меня работают=) Только вот такой вопрос: можно ли сделать так чтобы минутная стрелка перемещалась один раз в минуту, а не медленно двигалась по кругу? (аналогично часовая)

О. Конечно, можно. Для минутной стрелки нужно делать угол кратным величине pi/30. Например, так: u := round(u*30/pi)/(30/pi); или так: u := int(u*30/pi)/(30/pi); Функция round, напомню, округляет числа, а int - отбрасывает дробную часть. (Вообще-то между ними есть ещё одно очень серьёзное отличие: round возвращает целочисленное значение, а int - вещественное, но для данной задачи это не важно). Для часовой - думайте сами. :-)

В. На счёт второй формы, можно просто задать ей свойство visible в true, тогда её будет видно при запуске, но она будет типо второстепенной.

О. Можно. Я хотел просто продемонстрировать возможность в любой момент показать форму (метод show), а в обном из следющих уроков - спрятать её (метод hide). Для этих целей можно присваивать значения true и false свойству visible - оба способа практически равнозначны (в действительности и во втором способе вызываются методы show и hide, и в первом изменяются значения visible), но рекомендуют использовать методы, как более корректный с точки зрения объектно-ориентированного программирования подход.

В. Теперь на счёт закрашивания цветом фона и вообще цвета фона=) Как его (цвет фона) задавать? да и цвет линии=) В паскале для этого дела есть функции setcolor - для рисования и setbkcolor - для фона. В Делфи я ниче подобного не нашла=(

О. У canvas есть свойства brush (кисть) и pen (карандаш), так вот, за закрашивание областей отвечает кисть, а за рисование карандаш. У них есть куча свойств, в том числе и цвет. Нажмите f1, выделив компонент image, щёлкните по ссылке properties, найдите canvas, опять properties, и т.д. - почитайте сами что есть у brush и pen. Мы этим тоже обязательно займёмся, но немного позже.

В. И ещё на счёт паскаля, там анимацию можно делать двумя способами или страницами или перерисовывать, так вот, при перерисовывании сначала рисуется что-то цветом, потом закрашивается цветом фона, потом перерисовывается и т.д. Не знаю, можно ли с нашими стрелками сделать нечто подобное=)

О. В Паскале рисование производится непосредственно работой с видеокартой, в delphi тоже возможен подобный вариант с использованием, например, библиотеки directx, но сейчас мы рисуем используя возможности операционной системы. Рисунок у нас простенький, так что всё работает без проблем. В принципе можно эмулировать привычные Вам из Паскаля страницы с помощью двух одинаковых компонентов image, расположенных друг под другом, и меняя у поочерёдно меняя у них свойство visible.

В. И ещё один вопрос на счёт часов, то что графический таймер немножечко отстаёт от текстового - это нормально?

О. Надо уменьшить interval у таймера. :-)

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 07.02.2007 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Nero Basic Burning ROM 2018 VL 5 - 9 License corporate
ABBYY Lingvo x6 Английская Домашняя версия, электронный ключ
Quest Software. Toad for DBA Suite for Oracle
NauDoc Enterprise 10 рабочих мест
SAP Crystal Reports 2008 INTL WIN NUL License
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Мир OLAP и Business Intelligence: новости, статьи, обзоры
Мастерская программиста
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100