Знаний, полученных в предыдущих уроках, достаточно, чтобы
приступить к изучению механизмов ввода и вывода данных. Общая схема работы
программы примерно такова: пользователь вводит данные, программа их считывает,
производит с ними какие-то операции и выдаёт результат. Упрощённо: ввод,
обработка, вывод. Что мы уже умеем? Для ввода данных нам понадобятся такие
элементы как текстовое поле ввода (TEdit) или многострочное поле - TMemo,
CheckBox или RadioButton для выбора параметров и др. Для вывода можно
использовать текстовую метку (TLabel). Теперь разберём программную часть. Мы уже
умеем описывать переменные, знаем, что такое тип данных и какие бывают типы
(числа, строки и т.п.) Осталось лишь выяснить как связать визуальные элементы с
программным кодом. В примерах, рассмотренных в предыдущих уроках, мы задавали
значения переменным вручную (в коде), но это конечно же неприемлемо ни для одной
программы. Программа должна быть универсальной и обрабатывать те данные, которые
передал пользователь. Для ввода и вывода будут использоваться некоторые функции.
Что такое функции, зачем они нужны, и как с ними работать, мы рассмотрели на
прошлом уроке. Ну что, ближе к делу?
Ввод на примере TEdit
Текстовое поле ввода (TEdit) - простой и в то же время удобный
элемент для ввода данных. В поле мы можем ввести и число и текст - никаких
ограничений нет. Итак, наша первая задача - узнать, что введено в поле. Для
этого мы должны обратиться к свойствам этого объекта. За текст, находящийся в
поле, отвечает свойство Text. Именно им мы и воспользуемся.
Попробуем считать число, которое будет введено... Расположим на форме само поле
(TEdit) и кнопку (TButton). Создадим обработчик нажатия кнопки и сделаем
следующее: объявим переменную целочисленного типа, а затем попробуем поместить в
неё значение, которое введено в поле.
procedure TForm1.Button1Click(Sender: TObject);
var A: Integer;
begin
A:=Edit1.Text;
end;
Казалоось бы, всё верно - переменную мы объявили, и просто
хотим узнать, что введено в поле. Попробуем запустить (F9) -
всё не так просто! Компилятор сообщает об ошибке:
[Error] Unit1.pas: Incompatible types: 'Integer' and 'TCaption'
Здесь сказано, что типы данных Integer и TCaption
не соответствуют друг другу. TCaption - это тип данных свойства
Text у TEdit. Этот тип "обозначает" текстовую строку, т.е. любые символы.
Становится понятнее? В поле ввода мы можем ввести не только цифры, но и буквы и
даже любые знаки, какие есть на клавиатуре (а на самом деле - вообще любые
символы из кодовой таблицы). Однако наша переменная - число! Получается, что мы
хотим в качестве числа записать символы. Непорядок! Да, вы скажете: но мы ведь
будем вводить в поле цифры, а не буквы... Верно, но знает ли об этом компилятор?
Конечно нет. А уговорить его не удастся :-)
Несоответствие типов данных - частая ошибка. Преобразовывать
одни типы данных в другие требуется очень часто. Наш пример - яркое тому
подтверждение. Чтобы работать с числом, мы должны введённый текст (именно текст)
преобразовать в число.
Преобразования могут выполняться разными способами. Основной
из них - применение специальных функций. Функции принимают один из несколько
параметров (аргументов), одним из которых является переменная или значение,
подлежащее преобразованию. Функция выполняет какие-то операции и возвращает
значение нужного нам типа.
Для преобразования текста (строки) в целое число служит
функция StrToInt(). Название абсолютно точно отражает
назначение функции. У функции единственный параметр - строка, а на выходе
получается число. Поэтому, чтобы наш пример работал, мы должны написать так:
procedure TForm1.Button1Click(Sender: TObject);
var A: Integer;
begin
A:=StrToInt(Edit1.Text);
end;
Теперь программа запустится. Попробуем ввести число и нажать
кнопку - никакой ответной реакции не наблюдается. Это верно, ведь мы кроме
считывания введённого числа ничего не запрограммировали. А теперь попробуем
ввести посторонние символы (т.е. не цифры) - программа "вылетит" с сообщением об
ошибке:
В сообщении указана и причина возникновения ошибки: "'abc'
- неверное целое число". Как избегать подобных сообщений, а вместо этого
выполнять свои действия, мы разберёмся позже.
Вывод данных на примере TLabel
Прежде чем делать вывод, давайте произведём с введённым числом
какие-нибудь операции. К примеру, давайте возведём число в квадрат. Как это
делается, вы уже знаете. Вывод осуществим в текстовую метку (TLabel). За текст
метки отвечает свойство Caption. В данном случае наши действия
должны быть обратными: при вводе мы заносили в переменную введённое в поле
значение, а при выводе мы должны значение из переменной перенести в элемент.
Caption у TLabel описывается тоже типом данных TCaption, т.е. это
текст. А значит мы должны сделать обратное преобразование, т.е. преобразовать
число в текстовую строку. Как называется функция для такого перевода, легко
догадаться - IntToStr(). Финальный вариант обработчика кнопки:
procedure TForm1.Button1Click(Sender: TObject);
var A: Integer;
begin
A:=StrToInt(Edit1.Text);
A:=Sqr(A);
Label1.Caption:=IntToStr(A)
end;
Запускаем программу и пробуем:
Простейшая программа ввода-вывода готова.
Где узнать о типах данных свойств?
Очень логичный вопрос - где узнать, какой тип данных имеет
свойство элемента, кроме как смотреть сообщения об ошибках? Ответ прост - нам
снова поможет редактор кода. После того, как мы ввели имя объекта и поставили
точку, появляется список всех доступных команд. Напротив свойств через двоеточие
указывается и тип данных:
Обратите внимание, что редактор автоматически отслеживает, какие команды
содержатся в коде и в этом списке всегда находятся только те пункты, которые
применимы в данной ситуации. Так, если написать "A:=Edit1.", то в
списке будет отсутствовать свойство Text, ведь тип переменной A
и тип этого свойства не совпадают:
При написании функции StrToInt() строка свойства
Text конечно же появится.
Обобщение сказанного
Мы рассмотрели механизм ввода-вывода на примере обработки
числа. Если обработке подлежит текст, то преобразовывать типы данных не
придётся. Подобным образом осуществляется ввод и вывод практически любых данных,
главное - выполнять преобразование одних типов в другие.
Для ввода целых чисел также есть удобный элемент -
TSpinEdit. Расположен он на вкладке Samples. По
внешнему виду похож на TEdit, только в поле ещё находятся две кнопки со
стрелками - для изменения значения. Допустимые границы числа задаются свойствами
MinValue и MaxValue, а само значение хранится в свойстве
Value.
Работа с вещественными числами
Следует упомянуть и о дробных числах, ведь иногда без них не
обойтись. В целом, их ввод и вывод практически такой же, как и целых чисел,
только используются функции StrToFloat() и FloatToStr().
Всё просто. Однако с вещественными числами есть одна проблема - разделитель
целой и дробной части. Дело в том, что нет определённости, какой символ считать
разделителем - точку или запятую. Какой символ выбирается - зависит от настроек
операционной системы (в Windows этот знак определяется в Панели управления
в разделе Язык и региональные стандарты). Таким образом, если заточить
программу под запятую, то на системах, где установлена точка, работать ничего не
будет и будут возникать ошибки во время работы. В то же время, под точку тоже
нельзя затачивать программу, ведь может стоять и запятая. К счастью, решение
есть. Есть переменная, которую нигде не нужно объявлять, но значение которой
можно менять - это переменная DecimalSeparator. Она объявлена в
модуле SysUtils и хранит тот символ, который будет считаться
разделителем. Установить нужное значение достаточно один раз - например при
запуске программы. Вот так можно установить разделителем точку:
procedure TForm1.FormCreate(Sender: TObject);
begin
DecimalSeparator:='.';
end;
Другие способы вывода
Помимо вывода в объекты (например, в TLabel) иногда удобно
выводить данные в виде маленьких отдельных окон. Для этой цели существуют
стандартные команды. В предыдущих уроках мы с ними уже встречались, но не
разбирали их подробно.
1. Простое окно с сообщением - ShowMessage()
Самое примитивное окно содержит указанный текст и кнопку
OK для закрытия окна. Вызвать такое окно можно процедурой
ShowMessage(), параметром которой является текст - он и будет отображён
в окне. Модифицируем нашу мини-программу, убрав TLabel и заменив строку вывода:
procedure TForm1.Button1Click(Sender: TObject);
var A: Integer;
begin
A:=StrToInt(Edit1.Text);
A:=Sqr(A);
ShowMessage(IntToStr(A));
end;
В этом случае мы увидим следующее:
Следует обратить внимание на то, что пока окно сообщения
находится на экране, интерфейс программы блокируется, а также прекращается
выполнение дальнейших команд. Только после нажатия на кнопку программа продолжит
свою работу.
2. Диалоговое окно - MessageDlg()
Диалоговые окна - более сложный тип окон. Диалоговые окна
часто используются для "общения" с пользователем. Однажды такое окно нами уже
использовалось - при закрытии окна программы мы спрашивали у пользователя,
действительно ли окно нужно закрыть. Теперь разберём работу с такими окнами
подробно.
Создаются диалоговые окна функцией MessageDlg().
Это именно функция, а не процедура. Возвращаемым значением является кнопка,
которую нажал пользователь. У функции 4 входных параметра:
В качестве возвращаемых функцией значений служат все те же
константы кнопок, только с тем отличием, что вместо "mb" они начинаются
на "mr" (сокращения от "modal button" и "modal result"
соответственно).
Изменим нашу программу - пусть результат выдаётся в
информационном окошке. Обратите внимание, насколько красивее выглядит такое
окно:
procedure TForm1.Button1Click(Sender: TObject);
var A: Integer;
begin
A:=StrToInt(Edit1.Text);
MessageDlg('Квадрат числа '+IntToStr(A)+' равен '+IntToStr(Sqr(A)),mtInformation,[mbOK],0);
end;
Примечание: Текстовые строки можно
объединять, просто складывая их - знак "+" (см. фрагмент кода выше). Сами строки
записываются в одиночных кавычках.
Ну и напоследок попробуем использовать диалог для уточнения у
пользователя дополнительной информации. К примеру, если введено отрицательное
число, будем спрашивать, нужно ли его возвести в квадрат... Код получится
приблизительно таким:
procedure TForm1.Button1Click(Sender: TObject);
var A: Integer;
begin
A:=StrToInt(Edit1.Text);
if A < 0 then
if MessageDlg('Число отрицательное. Возвести его в квадрат?',mtConfirmation,[mbYes,mbNo],0) = mrYes then
MessageDlg('Квадрат числа '+IntToStr(A)+' равен '+IntToStr(Sqr(A)),mtInformation,[mbOK],0);
end;
А результат будем таким:
Внешний вид окон всех типов:
3. Диалоговые окна MessageBox()
C помощью фунции MessageBox() можно также
выводить диалоговые окна. По внешнему виду они практически ничем не отличаются
от окон MessageDlg(), однако есть возможность указать и заголовок окна.
Для формирования строки кода с использованием MessageBox() есть
программа
Master MessageBox. C помощью неё можно быстро создать нужное
диалоговое окно. Проблема MessageBox() в том, что тип диалога и кнопки
задаются немного необычным образом.
Ввод с помощью диалогового окна
Специальные окошки существуют не только для вывода на экран,
но и для ввода. Примером такого окна является InputBox().
Функции передаётся 3 параметра: текст заголовка окна, текст пояснения и
значение, находящееся в поле при показе окна на экран. Введённую в поле строку
функция возвращает как значение-результат. Пример:
procedure TForm1.Button2Click(Sender: TObject);
begin
if InputBox('Загадка','Сидит дед, в сто шуб одет. Кто его раздевает - тот слёзы проливает. Кто это?','') = 'лук' then
MessageDlg('Правильно!',mtInformation,[mbOk],0)
else
MessageDlg('Вы не угадали.',mtWarning,[mbOk],0)
end;
Заключение
Мы рассмотрели способы ввода и вывода данных, а также
познакомились с диалоговыми окнами. Приёмы ввода-вывода используются практически
в любом приложении: в тех, которые имеют оконный интерфейс, это делается с
использованием визуальных объектов, а для консольных приложений - в режиме
командной строки.
Автор: Ерёмин Андрей
|