Графічні годинник (исходники

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 у таймера. 🙂

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*