Диалоги
Цель лекции
Изучение стандартных диалогов и компонента-контейнера изображений TImage.
Диалоги
В любой большой программе есть диалоги.
Информация, которую требуется получить от пользователя, может быть самой разной: какой файл открыть, какой файл создать, куда сохранить, какой выбрать шрифт, цвет, картинку… Можно, конечно, создавать все эти диалоги вручную, но гораздо удобней пользоваться стандартными диалогами - это проще, и эти диалоги используют язык установленной операционной системы. Тем более что от каждого диалога нам с вами потребуется всего пару-тройку свойств, и один метод - легче некуда! Все диалоги находятся на вкладке Dialogs Палитры компонентов.
TOpenDialog и TSaveDialog
Диалоги TOpenDialog и TSaveDialog предназначены, как нетрудно догадаться из их названия, для открытия и сохранения файлов:
Изучать работу диалогов мы с вами будем сразу на конкретных примерах. Чтобы не делать лишней работы, воспользуемся проектом MyNotebook из прошлой лекции, который вы должны были сохранить в папку 14-01. Если вы помните, в том проекте для хранения текста мы использовали файл MyText.txt, что не очень удобно - а вдруг пользователю захочется работать со многими файлами, а не только с одним? Вот как раз для этого нам и понадобятся два этих диалога.
Итак, откройте Lazarus. Если у вас открылся новый проект (или предыдущий), закройте его командой Файл -> Закрыть. Далее, командой Файл -> Открыть найдем и откроем проект MyNotebook (для этого нужно указать файл MyNotebook.lpi или MyNotebook.lpr). Обратите внимание: только что мы воспользовались стандартным диалогом открытия файла!
Когда проект с редактором текста откроется, установите в любое место формы по одному компоненту TOpenDialog и TSaveDialog. Эти компоненты будут невидимы для пользователя, поэтому их можно установить в любое место формы, например, прямо поверх Memo1. Выделите компонент TOpenDialog, разберемся с его свойствами. Как видите, их не очень много, да и нужны нам будут не все.
DefaultExt | - расширение имени файла по умолчанию. В зависимости от того, с каким типом файлов нам придется работать, такое у них будет и расширение. Если мы работаем с текстом, то лучше именам файлов давать расширение txt. Это необязательно, но так системе проще будет понять, с каким типом файлов ей придется работать. Так, если вы в Проводнике щелкните дважды по нашему прежнему файлу MyText.txt, то откроется стандартный Блокнот Windows, в котором будет загружен текст из этого файла. |
FileName | - имя файла. Можно сразу же указать имя файла, с адресом и расширением, но обычно это свойство оставляют пустым. После того, как диалог сработает, и пользователь выберет файл для открытия, то в этом свойстве будет и адрес, и имя этого файла. А они нам будут нужны в методе
Memo1.LoadFromFile() |
Filter | - фильтр типов файлов. Здесь можно задать фильтрацию файлов по их типам, используя маску файлов. В маске знак "*" означает любое количество любых символов. Например, в фильтре можно указать маски *.txt, что означает "любой файл с расширением txt", и(или) *.*, что означает "любой файл с любым расширением или без расширения". |
InitialDir | - папка (директория, каталог), используемая по умолчанию. Здесь указывается адрес папки, с которой диалог начнет свою работу. Заполнять это свойство имеет смысл лишь тогда, когда нужные файлы у вас будут храниться в каком-то одном, конкретном месте. В нашем случае мы не знаем, где пользователю захочется сохранять свои файлы, поэтому заполнять это свойство не нужно. |
Name | - имя компонента. С этим свойством вы уже знакомы, но тут нужно сделать одно замечание. Помните, в прошлой лекции я говорил, что если компонент один, то его можно не переименовывать? С кнопками этот совет хорош - к кнопкам в коде нам не приходится обращаться по имени. А вот к диалогам придется обращаться неоднократно. Судите сами, что проще будет набрать на клавиатуре:
OpenDialog1.FileName или OD.FileName? |
Title | - заголовок окна диалога. По умолчанию, он уже содержит нужный текст: "Открыть существующий файл". Если же вам захочется установить какое то свое, нестандартное название, например "Открыть мой текстовый файл", можете вписать его здесь. |
Со свойствами разобрались, остался метод. Метод этот - Execute.
Execute вызывает стандартное диалоговое окно, и дает пользователю сделать выбор. Если пользователь сделал свой выбор, то Execute вернет True. Если пользователь отказался делать выбор и закрыл окно, не указав файла, метод вернет False.
Настроим наш TOpenDialog:
- DefaultExt = .txt
- Name = OD
Теперь займемся фильтром. Выделите свойство Filter и щелкните по кнопке "…" справа от него. Откроется редактор фильтров, который мы заполним следующим образом:
Когда вы нажмете "ОК", Lazarus в свойстве Filter сгенерирует следующий фильтр:
Текстовые файлы|*.txt|Все файлы|*.*
Эту строку можно было бы написать и вручную, но воспользоваться Редактором фильтров все же удобней.
Теперь, когда мы настроили наш диалог открытия файлов OD, займемся кодом. Если вы помните, то загрузка текста из файла у нас происходила при нажатии кнопки "Читать", то есть, bRead. Щелкните дважды по этой кнопке, и вы попадете на код её события OnClick. Приведу текст этого события:
procedure TfMain.bReadClick(Sender: TObject); begin if FileExists('MyText.txt') then Memo1.Lines.LoadFromFile('MyText.txt') else ShowMessage('Файл MyText.txt не существует'); end;
Помните, мы вначале проверяли, существует ли этот файл, и затем, в зависимости от результата, предпринимали либо одно, либо другое действие. Так вот, с диалогами этого делать не нужно! Если пользователь выбрал файл, то нет смысла проверять - существует ли он. Конечно, существует, иначе пользователь не смог бы его выбрать. Чувствуете разницу? Новый код события будет таков:
procedure TfMain.bReadClick(Sender: TObject); begin if OD.Execute then Memo1.Lines.LoadFromFile(OD.FileName); end;
А теперь разница видна? Мы проверяем - если диалог сработал, то мы вызываем метод LoadFromFile, передавая ему в качестве параметра выбранный пользователем файл. Не забывайте, что в свойстве FileName диалога содержится имя выбранного файла вместе с его адресом и расширением. Если же диалог не сработал, то и делать ничего не нужно.
Теперь займемся диалогом сохранения файла TSaveDialog. А тут нам все уже известно - все свойства и метод Execute у него в точности такие, как и у TOpenDialog, разве что текст в свойстве Title другой. Именно поэтому я и дал эти диалоги парой.
Измените имя компонента на SD. Свойства DefaultExt и Filter настройте так же, как в OD. Все остальное остается без изменений. Теперь нам нужно вписать код сохранения файла. Делается это в событии OnClick кнопки "Сохранить". Новый код события такой:
procedure TfMain.bSaveClick(Sender: TObject); begin if SD.Execute then Memo1.Lines.SaveToFile(SD.FileName); end;
Код простой, и должен уже быть вам понятен без всяких комментариев. Сохраните проект и запустите его на выполнение. Посмотрите, как работает сохранение и загрузка файлов. Здесь есть один недостаток, если вы заметили: при сохранении уже открытого файла программа все равно запрашивает, куда сохранять текст. Этот недостаток мы исправим в ближайшей лабораторной работе.
TColorDialog
TColorDialog - диалог выбора цвета. Он очень прост. Все, что нам от него нужно, это свойство Color и метод Execute. Если диалог состоялся, то сложное свойство Color будет содержать выбранный пользователем цвет. Этот цвет можно присвоить свойству Color какого-то другого компонента. Например, свойство Color компонента TMemo отображает цвет фона данного компонента. Я, правда, говорил, что не стоит использовать в проекте попугайские расцветки, но наша программа учебная, к тому же мы будем устанавливать только те расцветки, которые выберет пользователь. А потому, установите на форму еще одну кнопку TButton, свойство Name которой переименуйте в bColor, а в свойстве Caption напишите Цвет. Не забудьте снять в свойстве Anchors закрепление к верхнему краю, и установить закрепление к нижнему, как мы делали это с остальными кнопками.
Далее, нам потребуется установить на форму компонент TColorDialog:
Этот компонент, как и все остальные компоненты, невизуальный, поэтому устанавливайте его, куда хотите. Свойство Name диалога переименуйте в CD. Обработчик OnClick для кнопки bColor очень простой:
procedure TfMain.bColorClick(Sender: TObject); begin if CD.Execute then Memo1.Color:= CD.Color; end;
Если диалог состоялся, фону редактора присваиваем тот цвет, который выбрал пользователь. Сохраните проект, запустите его и попробуйте менять цвета.
TFontDialog
TFontDialog - диалог выбора шрифта. В этом диалоге пользователь может выбрать как сам шрифт, так и его размеры, начертание, эффекты и цвет. Не путайте цвет фона и цвет шрифта! Белый или желтый текст, например, прекрасно читается на синем или черном фоне. Нам потребуется установить на форму один такой компонент:
Свойство Name компонента переименуйте в FD. В коде нам потребуется его сложное свойство Font, которое будет содержать тот шрифт, что выбрал пользователь, и которое мы сможем присвоить свойству Font другого компонента.
Также нам потребуется кнопка с именем bFont и текстом Шрифт в свойстве Caption. Не забывайте про привязки кнопок к нижней границе формы. Обработчик OnClick для кнопки такой:
procedure TfMain.bFontClick(Sender: TObject); begin if FD.Execute then Memo1.Font:= FD.Font; end;