Урок 4. Динамическое изменение внешнего вида программы
Исходные тексты программы в ближайшее время будут здесь. ;о)
Оператор if. Понятие переменной. Локальные переменные. Тип integer. Целочисленное деление. «Привязка» компонентов к краям формы. Событие OnResize формы.
Ну что же, раз у меня такая способная ученица, которая не только на отлично выполняет домашние задания, но и успевает заниматься дополнительно, то пора увеличивать сложность заданий. Этот урок получается довольно большим, но, думаю, не стоит его резать, поскольку вещи здесь тебе в основном знакомые. Что ты в полной мере и продемонстрировала на своём факультативе. Так что в значительной степени этот урок я пишу для наших читателей.
Давай сделаем так, чтобы внешний вид надписей изменялся при изменении размера окна программы. У метки Label4, в которой ты выводишь дату и время, будем изменять размер шрифта так, что бы надпись всегда занимала всю ширину окна. Все остальные надписи должны выравниваться по центру. Кроме того, мы запретим форме становиться меньше некоторого наперёд заданного размера.
Для этого нам потребуется оператор
if (условие)
then (команда1)
else (команда2);
Смысл этого оператора очень прост: если выполняется (условие), то выполняй команду1, иначе — выполняй команду2. Если нужно выполнить несколько команд, то их нужно заключить в операторные скобкиbegin – end. Я советую всегда использовать операторные скобки, даже если в них будет находиться всего одна команда. Конечно, текст программы немного увеличится, но, на мой взгляд, повысится её читабельность. Вот так:
if (условие)
then begin
(команда1);
(команда2);
end
else begin
(команда3);
end;
Обрати внимание на пунктуацию. Да, чуть не забыл, ветку else этого оператора можно опустить.
Ещё нам потребуются переменные. Переменная — это специально выделенный участок памяти компьютера для временного хранения информации. Переменная доступна по своему имени. Например, нам нужно использовать в каком-то участке программы некоторое число, которое рассчитывается в другом участке программы. Тогда мы должны создать переменную, присвоить ей нужное значение, после чего мы можем использовать имя этой переменной в выражениях, а программа вместо имени будет подставлять значение переменной. До сих пор мы обходились без переменных, но активно использовали свойства компонентов, которые можно рассматривать как переменные. (Свойства компонентов устроены немного сложнее, чем переменные, но используются они точно так же). Переменная характеризуется своим типом. Тип переменной определяет какого рода данные могут быть записаны в переменную. Скажем, если переменная целочисленная,
то ей можно присвоить только целые числа, переменной вещественного типа можно присвоить дробные числа, строковой переменной — текстовые строки и т.д. В Delphi существует огромное количество различных типов. Кроме того, программист может на основе имеющихся определить новые типы.
Итак, план действий:
1. В обработчик события OnTimer нашего таймера между заголовком процедуры и словом begin добавь код:
var w : integer;
Слово var говорит, что мы собираемся описать новые переменные. То, что это слово находится внутри процедуры, означает, что эти переменные будут локальными, то есть доступными только в этой процедуре. w — это имя нашей переменной, а integer означает, что переменная w будет целого типа. В тело процедуры поместим код:
w := Label4.Width+2*Label4.Left;
if w <= Form1.ClientWidth
then begin
Label4.Font.Size := Label4.Font.Size+1;
end;
if w > Form1.ClientWidth
then begin
Label4.Font.Size := Label4.Font.Size-1;
end;
Свойство ClientWidth формы возвращает ширину «клиентской» области окна программы, то есть той области, где могут размещаться компоненты. В первом условии мы проверяем что больше ширина «клиентской» области или ширина метки плюс ширина пустого пространства слева и справа от метки (мы просто умножаем свойство Left на 2, что гарантирует нам, что справа останется столько же места, как и слева) — именно это мы присвоили переменной w. Если ширина метки и пустого пространства меньше либо равно ширине формы, то увеличиваем размер шрифта метки на 1. Во втором условии проверяем тоже, только знак стоит больше, и в результате уменьшаем размер шрифта на 1.
Почему нельзя воспользоваться веткой else, и обойтись одним условием, а не двумя? Ха! А это тебе будет домашнее задание.
2. Добавим в тот же обработчик код:
Label1.Left := (Form1.ClientWidth-Label1.Width) div 2;
Label2.Left := (Form1.ClientWidth-Label2.Width) div 2;
Label3.Left := (Form1.ClientWidth-Label3.Width) div 2;
Label5.Left := (Form1.ClientWidth-Label5.Width) div 2;
То есть выравнивание по центру происходит в результате расчёта на какое расстояние от левого края нужно переместить каждую метку. Операция div — это целочисленное деление. Вспоминай арифметику на уровне 1 класса. Деление целых чисел, деление с остатком... Никаких дробей при использовании div ты не получишь.
3. Уменьшим ширину Memo1 так, что бы оно полностью умещалось на форме (исчезла бы горизонтальная полоса прокрутки). И увеличим высоту так, что бы могли уместиться две строчки. Изменим свойство Alignment на taCenter (теперь текст в Memo1 будет выравниваться по центру). Изменим свойства Anchors: akTop выставим в false, а akRight и akBottom — в true. Это означает, что теперь компонент Memo1 будет «привязан» к левому, правому и нижнему краям формы. То есть при изменении ширины окна Memo1 будет деформироваться, а при изменении высоты — смещаться вслед за нижним краем.
4. Аналогично п.3 можно привязать метку Label5 к нижнему краю и отвязать её от верхнего края, а вот привязка её к левому и правому краям ничего не даст — размер метки подстраивается автоматически под её содержимое.
5. Создадим у формы разработчик события OnResize (возникает при изменении размера формы) и введём в него следующий код:
if Form1.Width < 350
then begin
Form1.Width := 350;
end;
if Form1.Height < 370
then begin
Form1.Height := 370;
end;
Тем самым как только ширина станет меньше 350 пикселей, мы будем возвращать её к этому размеру. Аналогично высота формы будет ограничена 370 пикселами.
Домашнее задание. Переделать пункт 1, используя оператор if с двумя ветками. Разобраться почему два оператора if с одной веткой работают корректно, а один оператор с двумя ветками (казалось бы - полный аналог) работает плохо. Изменить условие в операторе так, что бы работало хорошо.
На следующем уроке мы сделаем графические часы.
Alёna: Картина маслом: ученица не сделала урок! ;о) Все мои комментарии по поводу этого урока выйдут только в следующей рассылке, с них (и, возможно, обсуждения проблем с программой (буде таковые возникнут) у наших подписчиков) мы начнём урок №5. И отныне это станет нашей маленькой традицией: сначала урок, помозговать над которым вам всем предлагается в гордом одиночестве, в случае проблем - ваш "плач Ярославны" на форуме и по мылу, указанному ниже, под чертой, а в следующем выпуске - цитаты из наиболее интересных и полезных диалогов, ваши "вопросы на засыпку" и наши ответы. Договорились? ;о) Всем удачи!
Все комментарии
(цензурные и по возможности грамотные) рассматриваются в порядке живой
очереди, принимаются к сведению и даже публикуются на сайте. Так что
если тебе есть что сказать по поводу вышепрочитанного - мыль сюда!!! ;)