Графічні годинник (исходники, документація), Документація, Програмування, статті

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>

*

*