Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Мансуров. Основы программирования в среде Lazarus. 2010

.pdf
Скачиваний:
45
Добавлен:
27.04.2021
Размер:
6.3 Mб
Скачать

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

____________________________________________________________________

m, s, t: real; begin

try

SetLength(a, n, n); {установка фактического размера массива Преобразование одномерного массива в двумерный} k:= 1;

for i:= 0 to n - 1 do for j:= 0 to n - 1 do begin

a[i, j]:= vector[k]; k:= k + 1;

end;

for k:= 0 to n - 2 do begin

for i:= k + 1 to n - 1 do begin

if (a[k, k]= 0) then begin

{перестановка уравнений} p:= k;

for r:= i to n - 1 do begin

if abs(a[r, k]) > abs(a[p, k]) then p:= r; end;

if p <> k then begin

for j:= k to n - 1 do begin

t:= a[k, j];

a[k, j]:= a[p, j]; a[p, j]:= t;

end;

t:= b[k]; b[k]:= b[p]; b[p]:= t;

end;

end; // конец блока перестановки уравнений m:= a[i, k] / a[k, k];

a[i, k]:= 0;

for j:= k + 1 to n - 1 do begin

a[i, j]:= a[i, j] - m * a[k, j]; end;

611

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

____________________________________________________________________

b[i]:= b[i] - m * b[k]; end;

end;

{Проверка существования решения} if a[n - 1, n - 1] <> 0 then begin

x[n - 1]:= b[n - 1] / a[n - 1, n - 1]; for i:= n - 2 downto 0 do

begin s:= 0;

for j:= i + 1 to n - 1 do begin

s:= s - a[i, j] * x[j]; end;

x[i]:= (b[i] + s) / a[i, i]; end; Memo1.Lines.Add('Решение:'); for i:= 0 to n - 1 do

Memo1.Lines.Add('x' + IntToStr(i + 1) + '=' + FloatToStr(x[i]));

end else

if b[n - 1] = 0 then Memo1.Lines.Add('Система уравнений' +

' не имеет решения.')

else

Memo1.Lines.Add('Система уравнений' +

' имеет бесконечное множество решений.');

except

on EInvalidOP do

Memo1.Lines.Add('Неправильные данные. Система уравнений' + ' не имеет решения.');

on EMathError do

Memo1.Lines.Add('Неправильные данные. Система уравнений' + ' не имеет решения.');

on EZeroDivide do

Memo1.Lines.Add('Неправильные данные. Система уравнений' + ' не имеет решения.');

on EOverflow do

Memo1.Lines.Add('Неправильные данные. Система уравнений' + ' не имеет решения.');

on EUnderflow do

612

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

____________________________________________________________________

Memo1.Lines.Add('Неправильные данные. Система уравнений' + ' не имеет решения.');

on EAccessViolation do

Memo1.Lines.Add('Неправильные данные. Система уравнений' + ' не имеет решения.');

end;

a:= nil; // освобождение памяти end;

procedure TForm1.StringGrid1KeyDown(Sender: TObject; var Key: Word; Shift:TShiftState);

begin

if (Key = VK_Return) then begin

if (StringGrid1.Col >= n) then begin

StringGrid1.Row:= StringGrid1.Row + 1; StringGrid1.Col:= 0;

Key:= 0; end;

end;

end;

procedure TForm1.FormShow(Sender: TObject); begin

StringGrid1.ColCount:= 1;

StringGrid1.RowCount:= 1; Edit1.SetFocus; Button3.Visible:= true; Button4.Visible:= false;

end;

procedure TForm1.Button1Click(Sender: TObject); begin

Memo1.Clear;

StringGrid1.Clean; StringGrid1.ColCount:= 1; StringGrid1.RowCount:= 1; Edit1.Clear; Edit1.SetFocus; Button3.Visible:= true; Button4.Visible:= false;

end;

procedure TForm1.Button2Click(Sender: TObject); begin

{освобождение памяти,

613

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

____________________________________________________________________

распределенной для динамических массивов} a:= nil;

vector:= nil; x:= nil;

b:= nil; Close();

end;

procedure TForm1.Button3Click(Sender: TObject); begin

Edit1.SetFocus;

if Length(Edit1.Text) = 0 // если пустая строка then exit;

n:= StrToInt(Edit1.Text); StringGrid1.ColCount:= n + 1; StringGrid1.RowCount:= n ; Stringgrid1.SetFocus; Button3.Visible:= false; Button4.Visible:= true;

end;

procedure TForm1.Button4Click(Sender: TObject); begin

if (StringGrid1.Col >= n) then begin

StringGrid1.Row:= StringGrid1.Row + 1; StringGrid1.Col:= 0;

end else

StringGrid1.Col:= StringGrid1.Col+1; end;

procedure TForm1.Button5Click(Sender: TObject); var i, j, k, code:integer;

begin

{Установка реальных размеров динамических массивов} SetLength(a, n, n);

SetLength(vector, n * n); SetLength(b, n); SetLength(x, n);

for j:= 0 to n - 1 do for i:= 0 to n - 1 do begin

val(StringGrid1.Cells[i, j], a[i, j], code); if code <> 0 then

begin

614

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

____________________________________________________________________

ShowMessage('Ошибка при вводе коэффициентов матрицы'); StringGrid1.SetFocus;

exit;

end;

end;

for j:= 0 to n - 1 do begin

val(StringGrid1.Cells[n, j], b[j], code); if code <> 0 then

begin

ShowMessage('Ошибка при вводе свободных членов'); StringGrid1.SetFocus;

exit;

end;

end;

code:=0;

{Преобразование двумерного массива в одномерный} k:= 1;

for j:= 0 to n - 1 do for i:= 0 to n - 1 do begin

vector[k]:= a[i, j]; k:= k + 1;

end;

{Вызов процедуры решения системы линейных алгебраических уравнений методом Гаусса}

Gauss(vector, b, x, n); end;

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

begin

if Key = #13 then begin

if Length(Edit1.Text) = 0 // если пустая строка then exit;

n:=StrToInt(Edit1.Text); StringGrid1.ColCount:= n + 1; StringGrid1.RowCount:= n ; Stringgrid1.SetFocus;

exit;

end;

{разрешаем только цифры, знак минус и кл. BackSpace} if not (Key in ['0' .. '9', #8])

615

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

____________________________________________________________________

then begin

Key:= #0; exit;

end;

end; initialization

{$I Unit1.lrs} end.

В программе пользователь может вводить коэффициенты и редактировать их прямо в TStringGrid. После нажатия кнопки "Решить" данные из

TStringGrid преобразуются в числовое представление и записываются в ди-

намические массивы a – матрица коэффициентов системы, b – вектор свобод-

ных членов. Далее осуществляется вызов процедуры Gauss()решения систе-

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

лученный вектор x[x1, x2, . . . , xn] преобразуется в строку и выводится на экран.

Для контроля ввода данных в Edit1 мы использовали метод, применен-

ный нами в 6.3.7.1. Для контроля ввода в StringGrid1 функцию Val(), а

при вычислениях применили механизм исключений.

6.3.10.3. Компоненты выбора

В этих компонентах можно организовать выбор каких-то элементов из списка. Весь список содержится в свойстве Items и имеет тип TString. Эле-

ментами списка являются строки. Строки нумеруются, начиная с нуля. Доступ к строке осуществляется с помощью указания индекса элемента в свойстве

Items, например Items[k] или свойства Items.Strings, например

Items.Strings[k].

Компонент TListBox

Рассмотрим компонент TListBox. Он расположен на странице

616

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

____________________________________________________________________

Standard. Основные свойства компонента:

MultiSelect – признак множественного выбора. Если MultiSelect = true, то разрешается выбор одновременно нескольких элементов.

ExtendedSelect – если ExtendedSelect= true и MultiSelect= true, то выбор нескольких элементов можно производить стандартным спосо-

бом, т.е. при нажатой клавише Shift можно выбрать несколько элементов,

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

Count – общее количество элементов в компоненте.

ItemIndex – индекс выбранного элемента (при MultiSelect= false).

Если выбрано несколько элементов (MultiSelect= true), то содержит ин-

декс элемента, на котором установлен фокус.

Selected[i] – если выбран элемент с индексом i, то значение этого свой-

ства равно true.

Sorted – если равно true, то элементы компонента автоматически сорти-

руются.

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

нику работы с этим компонентом. Поместите на форму два компонента

TListBox и три кнопки, так как показано на рис. 6.61.

Заполним программно ListBox1 содержимым текстового файла, в кото-

ром содержатся фамилии, допустим студентов. Затем будем просто помещать выбранные элементы в ListBox2. Сначала реализуем выбор одиночного эле-

мента.

617

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

____________________________________________________________________

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

Вот код этой программы:

unit Unit1;

{$mode objfpc}{$H+} interface

uses

Classes, SysUtils, FileUtil, LResources, Forms,

Controls, Graphics, Dialogs, StdCtrls;

type

{ TForm1 }

TForm1 = class(TForm)

Button1: TButton;

Button2: TButton;

Button3: TButton;

ListBox1: TListBox;

ListBox2: TListBox;

procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject);

618

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

____________________________________________________________________

procedure FormCreate(Sender: TObject); private

{private declarations } public

{public declarations } end;

var

Form1: TForm1; implementation { TForm1 }

procedure TForm1.Button2Click(Sender: TObject); begin

with ListBox1 do begin

if ItemIndex >= 0 then ListBox2.Items.Add(Items[ItemIndex]);

end;

end;

procedure TForm1.Button1Click(Sender: TObject); begin

ListBox2.Clear;

end;

procedure TForm1.Button3Click(Sender: TObject); begin

Close;

end;

procedure TForm1.FormCreate(Sender: TObject); var

619

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

____________________________________________________________________

tfile: TStringList; str: string;

begin

tfile:= TStringList.Create; tfile.LoadFromFile('List.txt'); str:= tfile.Text;

{$IFDEF WINDOWS}

str:= SysToUTF8(str); // преобразование в кодировку UTF-8

{$ENDIF}

with ListBox1 do begin

Items.Text:= str; end;

tfile.Free;

end; initialization

{$I unit1.lrs} end.

Если установить в ListBox2 свойство Sorted = true, то элементы будут выведены в отсортированном виде. При добавлении нового элемента, он будет помещен в нужное место автоматически.

В этой реализации, если при одном и том же выбранном элементе нажать на кнопку "Копировать" несколько раз, то этот элемент попадет в ListBox2

также несколько раз, т.е. строки в ListBox2 окажутся не уникальными.

Чтобы элементы в ListBox2 не повторялись, напишем функцию, кото-

рая проверяет не содержится ли уже этот элемент в ListBox2. Если такой элемент имеется, функция возвращает true, если нет, то false.

620