Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
osnovy_programmirovanija_v_srede_lazarus.pdf
Скачиваний:
183
Добавлен:
18.03.2015
Размер:
6.53 Mб
Скачать

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

begin

ShowMessage('Вы успешно авторизовались!');

Close();

end;

end;

procedure TForm1.FormCreate(Sender: TObject); begin

passw:= '1234'; n:= 1;

end;

procedure TForm1.Button1Click(Sender: TObject); begin

avtorization;

end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: char);

begin

if Key <> #13 then exit; avtorization;

end; initialization

{$I unit1.lrs}

end.

6.3.6.2. Компонент TLabeledEdit

В палитре компонентов на странице Additional имеется еще одна раз-

новидность однострочного редактора TLabeledEdit. Это фактически тот же

512

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

самый однострочный редактор, но с присоединенной к нему надписью. Во многих случаях для удобства пользователя над окнами редактирования необхо-

димо помещать некоторый текст, поясняющий, что за информацию следует вводить пользователю в этом окне. В этих случаях удобнее использовать

TLabeledEdit.

Довольно часто необходимо организовывать ввод числовой информации.

При этом всегда необходимо помнить, что данные вводятся в символьном виде,

то есть в свойстве Text компонентов TEdit и TLabeledEdit содержится строка символов. Если введено число, то для работы с ним как с числом, необ-

ходимо эту строку символов преобразовать во внутреннее представление числа.

Для этого используются функции StrToInt – для преобразования строки в целое число и StrToFloat – для преобразования в вещественное число. С

другой стороны, для того чтобы вывести числовые данные, например результа-

ты вычислений, необходимо выполнить обратное преобразование чисел в их строковое представление. Для этого применяются функции IntToStr – для преобразования целого числа в строку и FloatToStr – для преобразования вещественного числа в строку.

Рассмотрим пример.

Создайте новый проект. Поместите на форму три компонента

TLabeledEdit, четыре кнопки TSpeedButton, одну кнопку TBitBtn и

компонент TStatusBar, расположенную на странице Common Controls,

примерно так, как показано на рис. 6.30.

513

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

Рис. 6.30. Форма приложения

Для LabeledEdit1 раскройте свойство EditLabel и установите свойство Caption = "Первое число". Точно так же для LabeledEdit2 ус-

тановите свойство Caption = "Второе число" и для LabeledEdit3 Caption = "Результат".

Для SpeedButton1 установите свойство Caption = " + ". Для

SpeedButton2 свойство Caption = " - ", для SpeedButton3 Caption = " * " и SpeedButton2 свойство Caption = " / ".

Установите для всех кнопок SpeedButton свойства GroupIndex= 1,

свойства AllowAllUp= true.

В обработчик события OnShow для Form1 введите код:

procedure TForm1.FormShow(Sender: TObject);

begin

LabeledEdit1.SetFocus;

end;

В обработчик события OnKeyPress для LabeledEdit1 введите код:

procedure TForm1.LabeledEdit1KeyPress(Sender: TObject;

var Key: char);

514

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

begin

if Key = #13 then begin

LabeledEdit2.SetFocus; SpeedButton1.Down:= false; SpeedButton2.Down:= false; SpeedButton3.Down:= false; SpeedButton4.Down:= false; exit;

end;

end;

В обработчик события OnClick для SpeedButton1 введите код:

procedure TForm1.SpeedButton1Click(Sender: TObject);

begin

LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)

+ StrToInt(LabeledEdit2.Text));

StatusBar1.SimpleText:= 'Сложение';

LabeledEdit1.SetFocus;

LabeledEdit1.SelectAll;

end;

В обработчик события OnClick для SpeedButton2 введите код:

procedure TForm1.SpeedButton2Click(Sender: TObject);

begin

LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)

- StrToInt(LabeledEdit2.Text));

515

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

StatusBar1.SimpleText:= 'Вычитание';

LabeledEdit1.SetFocus;

LabeledEdit1.SelectAll;

end;

В обработчик события OnClick для SpeedButton3 введите код:

procedure TForm1.SpeedButton3Click(Sender: TObject);

begin

LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)

* StrToInt(LabeledEdit2.Text));

StatusBar1.SimpleText:= 'Умножение';

LabeledEdit1.SetFocus;

LabeledEdit1.SelectAll;

end;

В обработчик события OnClick для SpeedButton4 введите код:

procedure TForm1.SpeedButton4Click(Sender: TObject);

begin

LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)

div StrToInt(LabeledEdit2.Text));

StatusBar1.SimpleText:= 'Деление нацело';

LabeledEdit1.SetFocus;

LabeledEdit1.SelectAll;

end;

Здесь новым для нас является компонент TStatusBar, который позволя-

ет выводить в окне так называемую строку состояния. В этой строке приложе-

516

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

ние обычно выводит различную вспомогательную информацию. В нашей про-

грамме будет выводиться информация о последней выполненной операции.

В строке состояния можно определить одну или несколько независимых панелей. Если вы хотите иметь всего одну панель, то установите свойство

SimplePanel = true. В этом случае для вывода текста в строку состояния используйте свойство SimpleText. Если вам необходимо иметь несколько панелей установите свойство SimplePanel = false. Тогда для вывода текста в нужную панель используйте свойство Panels[k], где номер k панели

(нумерация с 0) или подсвойство Items, например:

StatusBar1.Panels[0].Text:= 'Какой либо текст'; StatusBar1.Panels.Items[0].Text:= 'Какой либо текст';

Откомпилируйте и запустите программу. Опробуйте работу кнопок.

В процессе ввода информации пользователи довольно часто допускают ошибки. В большинстве случаев эти ошибки носят случайный и непреднаме-

ренный характер, но могут вызвать сбой или даже аварийное завершение про-

граммы. Поэтому программист должен предусматривать соответствующие ме-

ры защиты своих программ от такого рода ошибок.

В нашем примере мы реализовали действия для целых чисел. При вводе чисел пользователь может, например, ввести недопустимый символ или вместо целого ввести вещественное число. В этой программе никакого контроля при вводе нет. В таких случаях программа, как правило, аварийно завершается. В

2.1.14 и 2.1.25 мы уже касались этого вопроса.

При возникновении какой-либо ошибочной ситуаций (говорят еще исклю-

чительной ситуации) генерируется так называемое исключение. К возникнове-

нию исключений могут привести не только действия пользователя, но и ряд других обстоятельств. Например, обращение к несуществующему файлу, обра-

517

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

щение к устройству, которое в этот момент не готово, выход за пределы выде-

ленной динамической области памяти, деление на ноль, переполнение разряд-

ной сетки и пр. Программист обязан и для таких случаев предусмотреть какие-

то действия, чтобы не допустить краха своей программы.

Отвлечемся на некоторое время от изучения компонентов и рассмотрим некоторые способы обнаружения и организации соответствующей реакции программы в случае возникновения каких-либо ошибочных ситуаций.

6.3.7 Обработка исключений. Компонент TMaskEdit. Организация кон-

троля ввода данных

Для обработки стандартных исключений в Lazarus имеются специальные классы. Если в программе не предусмотрена обработка какого-нибудь исклю-

чения, то оно обрабатывается глобальным обработчиком. Он обеспечивает стандартную реакцию на возникшее исключение – выводит предупреждение на экран с кратким описанием причины, вызвавшее исключение, рис. 6.31.

Рис. 6.31. Стандартная реакция на исключение

Здесь указано, что произошла попытка деления на ноль и предлагаются ва-

рианты действий – продолжить выполнение программы или завершить ее.

В большинстве случаев стандартной реакции оказывается недостаточной.

Поясню примером. Предположим, в программе создается временный файл, ко-

торый после завершения программы должен быть удален. Пусть во время рабо-

518

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

ты программы с файлом произошла ошибка. Скажем, был прочитан недопусти-

мый символ. Обработка такой ошибки программистом не был предусмотрен.

Тогда последует стандартная реакция, рис. 6.32.

Рис. 6.32. Стандартная реакция на исключение

Пользователь закрывает программу, нажав кнопку Cancel. А временный файл, который должен был быть уничтожен, останется на диске! Существуют очень много программ, которые оставляют после своей работы всякий "мусор"

на диске, если они завершаются аварийно. И это происходит из-за того, что программист не предусмотрел соответствующих действий по очистке мусора в случае возникновения исключительных ситуаций.

В таких случаях гораздо лучше, если программист организует свою собст-

венную обработку исключения, в которой и выполнит очистку мусора. Кроме того, программист знает логику работы своего приложения, знает – где именно произошло исключение и, в большинстве случаев, почему это произошло, по-

этому он может выдать пользователю более развернутое описание причины ошибки, к тому же на русском языке, а также предусмотреть такие действия,

которые могли бы пользователю продолжить работу (если это возможно).

Рассмотрим некоторые классы исключений.

EConvertError – ошибка преобразования типов. Чаще всего происходит при преобразовании строки в число.

EDivByZero – попытка деления целого числа на ноль.

EZeroDivide – попытка деления вещественного числа на ноль.

519

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

ERangeError – выход за пределы допустимого диапазона индекса или порядкового типа.

EIntOverflow – переполнение в операциях с целыми числами, т.е. по-

пытка присвоения переменной целого типа значения больше допустимого.

EOverflow – переполнение в операциях с вещественными числами.

EUnderflow – потеря значащих разрядов в операциях с вещественными

числами.

EAccessViolation – попытка обращения к недействительному адресу в памяти. Чаще всего возникает из-за неправильной работы с указателями.

Для обработки исключений используются две конструкции. Первая конст-

рукция имеет вид:

try

< Потенциально "опасные" операторы, при выполнении которых могут возникнуть исключительные ситуации >

except

on класс исключения 1 do < оператор обработки исключения 1 >; on класс исключения 2 do < оператор обработки исключения 2 >;

………………………………………………………………………………………………………………………………

on класс исключения n do < оператор обработки исключения n >;

else

< операторы обработки остальных исключений >

end;

Данная конструкция означает, что после ключевого слова try и до клю-

чевого слова except следуют операторы, при выполнении которых возмож-

но возникновение исключений. После except следуют операторы, которые

520

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

образуют секцию обработки исключений. Признаком конца секции служит ключевое слово end. Внутри секции программист указывает классы исключе-

ний (говорят еще типы исключений) после слова on, а затем после ключевого слова do оператор обработки исключения, причем оператор может быть со-

ставным. После необязательного else следуют операторы обработки исклю-

чений, не вошедшие в перечень on. Если программисту нужно только устано-

вить сам факт исключения, независимо от типа, то он может просто записать обработчик исключения после слова except.

Вторая конструкция имеет вид:

try

<Потенциально "опасные" операторы, при выполнении которых могут возникнуть исключительные ситуации >

finally

<операторы, которые должны быть выполнены в любом случае, незави-

симо от того, произошло исключение или нет >

end;

В чем их различие? В конструкции try..except если при выполнении операторов секции try возникло исключение, то управление передается в сек-

цию except, где и происходит обработка исключения. Если же исключения не произошло, то операторы блока except просто пропускаются. В конструкции try..finally операторы будут выполнены независимо от того, произошло исключение или нет.

Рассмотрим пример:

try

num:=StrToInt(Stroka);

except

521

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

on EConvertError do

ShowMessage('Ошибка преобразования строки в целое число');

end;

Здесь сообщение будет выведено только в том случае, когда невозможно преобразование строки символов в целое число, то есть когда возникнет ис-

ключение EConvertError.

Конструкции try..except и try..finally могут быть вложены друг в друга на неограниченную глубину. Рассмотрим реализацию примера с файлом.

Procedure Test; var

F: TextFile; number: integer; s: string;

begin

AssignFile(F, 'Data.txt');

Rewrite(F);

s:= '12#4';

// В файл намеренно записывается

Writeln(F, s);

// ошибочная строка символов

Reset(F);

 

try

// начало секции (блока) try..except

Readln(F, s);

 

try

// начало секции try..finally

number:= StrToInt(s);

finally

CloseFile(F); // эти два оператора будут выполнены

DeleteFile('Data.txt'); // в любом случае

522

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

end; // конец секции try..finally

except

on EConvertError do

ShowMessage('Ошибка преобразования'); end; // конец секции try..except

end;

Вернемся к примеру, в котором осуществляется ввод двух целых чисел и выполняются четыре арифметических действия (сложение, вычитание, умно-

жение и деление нацело), рис. 6.30. Модифицируем программу, добавив в него обработку исключений. Перепишите обработчики события OnKeyPress для

LabeledEdit1 и событий OnClick кнопок SpeedButton1, SpeedButton2, SpeedButton3 и SpeedButton4 в виде:

procedure TForm1.LabeledEdit1KeyPress(Sender: TObject; var Key: char);

begin

if Key = #13 then begin

try StrToInt(LabeledEdit1.Text);

except

on EConvertError do begin

ShowMessage('Ошибка преобразования! Вероятно, ' +

'Вы ошиблись при вводе числа');

exit;

end;

end;

523

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

LabeledEdit2.SetFocus; SpeedButton1.Down:= false; SpeedButton2.Down:= false; SpeedButton3.Down:= false; SpeedButton4.Down:= false; exit;

end;

end;

procedure TForm1.SpeedButton1Click(Sender: TObject); begin

try LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)

+ StrToInt(LabeledEdit2.Text));

except

on EConvertError do begin

ShowMessage('Ошибка преобразования! Вероятно, ' + 'Вы ошиблись при вводе второго числа');

exit;

end;

end;

StatusBar1.SimpleText:= 'Сложение';

LabeledEdit1.SetFocus;

LabeledEdit1.SelectAll;

end;

procedure TForm1.SpeedButton2Click(Sender: TObject); begin

524

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

try LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)

- StrToInt(LabeledEdit2.Text));

except

on EConvertError do begin

ShowMessage('Ошибка преобразования! Вероятно, ' + 'Вы ошиблись при вводе второго числа');

exit;

end;

end;

StatusBar1.SimpleText:= 'Вычитание';

LabeledEdit1.SetFocus;

LabeledEdit1.SelectAll;

end;

procedure TForm1.SpeedButton3Click(Sender: TObject); begin

try LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)

* StrToInt(LabeledEdit2.Text));

except

on EConvertError do begin

ShowMessage('Ошибка преобразования! Вероятно, ' +

'Вы ошиблись при вводе второго числа');

exit;

end;

end;

525

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

StatusBar1.SimpleText:= 'Умножение';

LabeledEdit1.SetFocus;

LabeledEdit1.SelectAll;

end;

procedure TForm1.SpeedButton4Click(Sender: TObject); begin

try LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)

div StrToInt(LabeledEdit2.Text));

except

on EConvertError do begin

ShowMessage('Ошибка преобразования! Вероятно, ' + 'Вы ошиблись при вводе второго числа');

exit;

end;

on EDivByZero do begin

ShowMessage('Ошибка! Произошло деление на ноль. Вероятно, ' + 'Вы ошиблись при вводе второго числа');

exit;

end;

end;

StatusBar1.SimpleText:= 'Деление нацело';

LabeledEdit1.SetFocus;

LabeledEdit1.SelectAll;

end;

526

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

Теперь при вводе недопустимого символа для целого числа, а также при вводе числа 0 в качестве второго операнда программа перехватывает исключе-

ния и реагирует соответствующим образом.

Имейте в виду, если вы запускаете программу из среды Lazarus, то исклю-

чения будет перехватывать отладчик. Поэтому лучше запускать программу из командной строки или в настройках окружения для отладчика добавьте нужные вам типы исключений в список игнорирования.

Обработку исключений вполне можно применять и в консольных прило-

жениях. Вспомним программу из 2.1.14. Организуем контроль ввода данных,

используя механизм исключений.

program int_operations_control; {$mode objfpc}{$H+}

uses

CRT, FileUtil, SysUtils; var

A, B, C: integer; begin

writeln(UTF8ToConsole('Введите два числа')); readln(A, B);

writeln('A= ', A, ' B= ', B); C:= A + B;

writeln(UTF8ToConsole('Демонстрация сложения, C= '), C); C:= A * B;

writeln(UTF8ToConsole('Демонстрация умножения, C= '), C); try

C:= A div B;

writeln(UTF8ToConsole('Демонстрация деления нацело, C= '),

C);

527

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

except

on EDivByZero do

begin

writeln(UTF8ToConsole('Ошибка!! Деление на ноль.')); writeln(UTF8ToConsole('Нажмите любую клавишу'));

readkey;

exit;

end;

end;

C:= A mod B;

writeln(UTF8ToConsole('Остаток от деления, C= '), C);

C:= A - B;

writeln(UTF8ToConsole('Демонстрация вычитания, C= '), C); writeln(UTF8ToConsole('Нажмите любую клавишу'));

readkey;

end.

Сравните эту программу с программой из 2.1.25.

Контроль и обработку ошибок с применением механизма исключений удобнее использовать, когда работа программы уже не зависит от действий пользователя, т.е. все необходимые данные от пользователя уже получены,

программа перешла непосредственно к обработке данных – идут вычисления,

происходит чтение и запись в файлы, обращения к различным внешним уст-

ройствам и т.д. На этапе же ввода данных, когда пользователь в режиме диало-

га вводит какие-то данные с клавиатуры, удобнее использовать другой способ контроля. Поскольку обработка исключений происходит после завершения ввода пользователем, то есть этим происходит только констатация факта, что ошибка пользователем уже совершена. Приходится организовывать повторный ввод, причем с того места, где пользователь ошибся. А это приведет к усложне-

528

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]