Модуль FormsABC: создание простого интерфейса

Просмотров: 54114

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

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

Создадим каркас приложения:

uses FormsABC;
 
begin
MainForm.Title := 'Вычисление определенного интеграла';
MainForm.SetSize(500,350);
MainForm.CenterOnScreen;
end.

После запуска мы увидим на экране главную форму с заданным размером и заголовком, центрированную относительно экрана.

Добавим на форму компоненты, отвечающие за параметры a,b,N и выбор функции ([a,b] - отрезок интегрирования, N - количество отрезков разбиения):

uses FormsABC;
 
var
a := new RealField('a:');
f1 := new FlowBreak;
b := new RealField('b:');
f2 := new FlowBreak;
N := new IntegerField('N:');
f3 := new FlowBreak;
tl := new TextLabel('Функция: ');
f4 := new FlowBreak;
cb := new ComboBox;
f5 := new FlowBreak(50);
s1 := new Space(20);
ok := new Button('Вычислить');
 
begin
MainForm.Title := 'Вычисление определенного интеграла';
MainForm.SetSize(500,350);
MainForm.CenterOnScreen;
end.

После запуска мы увидим следующее окно:

Здесь f1 := new FlowBreak и аналогичные добавляют переход на новую строку при вставке следующего компонента, f5 := new FlowBreak(50) пропускает дополнительно 50 пикселей по вертикали, s1 := new Space(20) пропускает 20 пикселей по горизонтали.

Обратим внимание, что на самом деле компоненты вставляются не на саму форму, а на панель MainPanel, которая лежит поверх формы и обеспечивает последовательное добавление компонентов.

Теперь разместим справа на форме компонент TextBox, на который будем выводить результаты. Для этого необходимо знать, что MainPanel выровнена на форме так, что заполняет всё пространство формы. Изменим выравнивание MainPanel на выравнивание по левому краю формы и ширину MainPanel:

  mainPanel.Dock := DockStyle.Left;
mainPanel.Width := 150;

После этого добавим на форму компонент TextBox. Обратим внимание, что TextBox должен размещаться именно на форме, а не на MainPanel. Для этого изменим вначале переменную ParentControl на значение MainForm, что означает, что все следующие компоненты будут размещаться на главной форме:

  ParentControl := MainForm;
tb := new TextBox;

Выравнивание нашего TextBox, наоборот, изменим так, чтобы он занимал оставшееся от MainPanel пространство формы:

  tb.Dock := DockStyle.Fill;

В итоге получим приложение:

uses FormsABC;
 
var
a := new RealField('a:');
f1 := new FlowBreak;
b := new RealField('b:');
f2 := new FlowBreak;
N := new IntegerField('N:');
f3 := new FlowBreak;
tl := new TextLabel('Функция: ');
f4 := new FlowBreak;
cb := new ComboBox;
f5 := new FlowBreak(50);
s1 := new Space(20);
ok := new Button('Вычислить');
tb: TextBox;
 
begin
MainForm.Title := 'Вычисление определенного интеграла';
MainForm.SetSize(500,350);
MainForm.CenterOnScreen;
mainPanel.Dock := DockStyle.Left;
mainPanel.Width := 150;
 
ParentControl := MainForm;
tb := new TextBox;
tb.Dock := DockStyle.Fill;
end.

Запустив его, увидим окончательное размещение компонентов:

Инициализируем свойства компонентов начальными значениями переменных (a=0, b=1, N=10), а также заполним выпадающий список cb выражениями функций, от которых будем далее вычислять опеределнный интеграл :

  b.Value := 1;
N.Value := 10;
cb.Items.Add('sin');
cb.Items.Add('cos');
cb.Items.Add('x^2');
cb.SelectedIndex := 0;

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

type Fun = function (x: real): real;
 
var funs: array of Fun := (sin,cos,sqr);
 
function CalcIntegral(a,b: real; N: integer; f: Fun): real;
begin
Result := 0;
var x := a;
var h := (b-a)/N;
for var i:=0 to N-1 do
begin
Result += f(x);
x += h;
end;
Result *= h;
end;

Массив funs будет содержать все возможные функции, от которых мы сможем вычислять определенный интеграл.

Наконец, самое главное: создадим обработчик кнопки ok и присвоим его событию нажатия на кнопку ok.Click:

procedure MyClick;
begin
var f := funs[cb.SelectedIndex];
var res := CalcIntegral(a.Value,b.Value,N.Value,f);
tb.AddLine(Format('Интеграл({0},{1},{2},{3}) = {4}',a.Value,b.Value,N.Value,cb.SelectedValue,res.ToString));
end;
 
...
ok.Click += MyClick;

В обработчике MyClick происходит основная работа: из массива funs выбирается нужная функция, вычисляется интеграл (исходные значения параметров берутся из свойств компонент), после чего в TextBox выводится строка результата.

В заключение перенесем инициализацию компонент в процедуру InitControls.

Ниже приводится полный код приложения:

uses FormsABC;
 
type Fun = function (x: real): real;
 
var funs: array of Fun := (sin,cos,sqr);
 
function CalcIntegral(a,b: real; N: integer; f: Fun): real;
begin
Result := 0;
var x := a;
var h := (b-a)/N;
for var i:=0 to N-1 do
begin
Result += f(x);
x += h;
end;
Result *= h;
end;
 
var
a := new RealField('a:');
f1 := new FlowBreak;
b := new RealField('b:');
f2 := new FlowBreak;
N := new IntegerField('N:');
f3 := new FlowBreak;
tl := new TextLabel('Функция: ');
f4 := new FlowBreak;
cb := new ComboBox;
f5 := new FlowBreak(50);
s1 := new Space(20);
ok := new Button('Вычислить');
tb: TextBox;
 
procedure MyClick;
begin
var f := funs[cb.SelectedIndex];
var res := CalcIntegral(a.Value,b.Value,N.Value,f);
tb.AddLine(Format('Интеграл({0},{1},{2},{3}) = {4}',a.Value,b.Value,N.Value,cb.SelectedValue,res.ToString));
end;
 
procedure InitControls;
begin
MainForm.Title := 'Вычисление определенного интеграла';
MainForm.SetSize(500,350);
MainForm.CenterOnScreen;
mainPanel.Dock := DockStyle.Left;
mainPanel.Width := 150;
 
b.Value := 1;
N.Value := 10;
cb.Items.Add('sin');
cb.Items.Add('cos');
cb.Items.Add('x^2');
cb.SelectedIndex := 0;
ok.Click += MyClick;
 
ParentControl := MainForm;
tb := new TextBox;
tb.Dock := DockStyle.Fill;
end;
 
begin
InitControls;
end.

Запустив его, будем менять параметры вычислений и, нажимая на кнопку «Вычислить», отображать результаты в окне TextBox:

Вуаля!

Новости

19.01.17. Добавлена операция безопасного среза: a?[-1:5:2]

29.08.16. Вышла версия 3.2. Реализован оператор yield.

12.02.16. Вышла версия 3.1. Добавлены кортежи в стиле (a,b) и кортежное присваивание (a,b) := (b,a)

31.12.15. Версия 3.0.0.1128. Реализованы обобщенные методы расширения для операций

Случайная программа

// Ханойские башни
// Уровень сложности: 1

procedure Hanoi(n,f,t,w: integer);
begin
  if n=0 then exit;
  Hanoi(n-1,f,w,t);
  // Переложить диск со стержня f
  // на стержень t
  writeln(f,'->',t);
  Hanoi(n-1,w,t,f);
end;

const n=8; // Количество дисков

begin
  Hanoi(8,1,2,3);
end.