Графічний годинник (вихідники, документація) - Програмні продукти
delphi дозволяє малювати майже будь-де. Можна малювати на формі, можна малювати на мітці, навіть малювати безпосередньо на екрані! Але краще використовувати все-таки спеціальний компонент timage вже хоча б тому, що цей компонент сам буде стежити потім, щоб при перемальовуванні вікна твоєї програми, твої каракулі теж перемальовувалися. Якщо ти намалюєш щось, наприклад, на формі, то при згортанні вікна програми твій малюнок зітреться.
Якщо на твоїй формі місця для такого годинника немає, пропоную включити в нашу програму ще одну форму.
0. За допомогою кнопки "new form" або пункту меню "file/new form" створюєш нову форму. Тиснеш на кнопочку «save». Вводиш якесь ім'я для цього нового модуля (звичайно можна залишити і unit2, але краще використовувати осмислені імена).
1. Поміщаєш на нову форму компонент image (палітра additional, 6-а кнопка у вигляді картинки) на форму. Властивість align виставляєш в alclient, в результаті зображення буде розтікатися по всій формі.
2. Кладеш на форму timer. Створюєш йому обробник події наtimer.
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. У цьому списку вказуються всі модулі, підключені до вашої програми. В кінець цього списку через кому постав ім'я свого нового модуля. При запуску програми відкриватиметься твоя перша форма, щоб відкрити другу, потрібно дати команду
Запусти програму. Годинник працює. Тільки стрілки не стираються. Потрібно очищати 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);
Питання та відповіді
В. Наче годинник зі стрілочками у мене працює =) Тільки ось таке питання: чи можна зробити так щоб хвилинна стрілка переміщалася один раз на хвилину, а не повільно рухалася по колу? (аналогічно годинна)
В. На рахунок другийформи, можна легко задати їй властивість visible в true, тоді її буде видно при запуску, але вона буде нібито другорядною.
О. Можна. Я хотів просто продемонструвати можливість у будь-який момент показати форму (метод show), а в одному з наступних уроків - сховати її (метод hide). Для цих цілей можна присвоювати значення true і false властивості visible - обидва способи практично рівнозначні (насправді і в другому способі викликаються методи show і hide, і в першому змінюються значення visible), але рекомендують використовувати методи як коректніший з точки зору об'єктно- орієнтованого програмування підхід.
В. Тепер на рахунок зафарбовування кольором тла і взагалі кольору тла =) Як його (колір тла) задавати? та й колір лінії=) У паскалі для цієї справи є функції setcolor – для малювання та setbkcolor – для фону. У Делфі я нічого такого не знайшла = (
О. У canvas є властивості brush (пензель) і pen (олівець), отож, за зафарбовування областей відповідає кисть, а за малювання олівець. Вони мають купу властивостей, зокрема і колір. Натисніть f1, виділивши компонент image, клацніть на посилання properties, знайдіть canvas, знову properties, і т.д. - Почитайте самі, що є у brush і pen. Ми цим теж обов'язково займемося, але трохи згодом.
І ще на рахунок паскаля, там анімацію можна робити двома способами або сторінками або перемальовувати, так ось, при перемальовуванні спочатку малюється щось кольором, потім зафарбовується кольором фону, потім перемальовується і т.д. Не знаю, чи можна з нашими стрілками зробити щось подібне.
В. І ще одне питання на рахунок годинника, те що графічний таймер трішечки відстає від текстового - це нормально?