Form Tutorial/ja

From Lazarus wiki
Jump to navigationJump to search

Deutsch (de) English (en) suomi (fi) 日本語 (ja) 中文(中国大陆)‎ (zh_CN)

日本語版メニュー
メインページ - Lazarus Documentation日本語版 - 翻訳ノート - 日本語障害情報

Lazarusでフォームを用いるための短いイントロダクション。

フォームとは何か

フォーム (class TForm)はapplicationのユーザーインターフェースとなるウインドウもしくはダイアログを表す。それは他のcomponents(例えば、ボタン、ラベル、編集ボックス、画像など)が挿入されるコンテナである。

最初のGUIアプリケーション

Lazarusのインストールが成功し、新しいアプリケーションプロジェクトを始めると、空のフォームが作られる。そうでなければ、新しい GUI アプリケーションを メインメニュー -> プロジェクト -> 新規プロジェクト -> アプリケーション OKで作ることができる。

今、新しい、全機能が使えるフォームを持つプロジェクトが作成された:

Form1 Designmodus.png

新しく作られたプロジェクトを実行するには、単にF9キーを押す、もしくはマウスでメインメニューアイコンStart.png(あるいは メインメニュー: 実行 -> 実行)をクリックする。プロジェクトはコンパイル、実行される。

特に面白いことが起こるわけではない。フォーム(Form1)はわずかに外見が変わり、ラスタグリッドの点々(個々のコンポーネントの位置付けの助けとなる)が消える(グリッドの点が見えてる間は、それがデザインモードにあることがわかる):

Form1 Designmodus.png -> Form1 Runmodus.png

次にフォームの上にTButtonを配することができる。これは後に第2のフォームを開くことを可能にするために使われる:

Component Palette上のStandard tabからTButtonを選ぶ。

TButtonStandardpalette.png

そしてフォームをクリックする: 「Button1」の名前とキャプションでForm1にボタンが配される。

このボタンに何かをさせるために、それをクリックすると、何か意図したことをするようにボタンに告げなければならない。これは単純なイベントである。このためクリックされた後に呼ばれる イベントハンドラが必要である。マウスに対するイベントハンドラはボタンはButton1をダブルクリックすることにより、極めて簡単に行える(もしくはオブジェクトインスペクタで、Button1 -> イベントタブ -> OnClick、次いで[...]をクリック)。これはButton1がクリックされると(設計段階ではなくruntime)にいつも呼ばれるプロシージャTForm1.Button1Clickをコードエディタに作り出す。

NeuesProjekt2.png

アプリケーションにButton1をクリックした後に何かをさせるために、プロシージャTForm1.Button1ClickのBeginEndの間にこのようにコードを加える:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption:='My first Form';  //Caption of Form1 is changed (text in formhead)
  //or
  Button1.Caption:='Hello';  //Caption of button is changed (shown text of button)
end;

そして、F9を押し、フォームを起動させる、ボタンをクリックしたときにフォームキャプションとボタンキャプションの双方が変わることに注意すること。

ちょっとした実験を行い、スタンダードコンポーネントの使い方を学んだ。始めるにあたり、以下のコンポーネントの例を試してみることを勧める:

TButton tbutton.png
TLabel tlabel.png
TEdit tedit.png
TMemo tmemo.png
TToggleBox ttogglebox.png
TCheckBox tcheckbox.png
TRadioButton tradiobutton.png
TListBox tlistbox.png
TComboBox tcombobox.png
TScrollBar tscrollbar.png

ここにさらに役に立つ情報があるLazarus Tutorial

2つ目のフォームを使う

このチュートリアルでは1つのプロジェクトで複数のフォームを使う方法を示す。この例で2つだけのフォーム、Form1(メインフォーム)とForm2が作られるが、追加のフォームについてもその仕方は同一である。

クリックされると新しいフォームを開くボタンがメインフォームにある。新しいフォームはまた、クリックされるとそれ自身を閉じ、メインフォームに帰ってくるボタンを有する。 もし最初のチュートリアル、 初めてのGUIアプリケーションを終えているのなら、TForm1.Button1Clickプロシージャのbeginとendの間のコードを削除しておく必要がある。そうしないと、新たなプロジェクト(アプリケーション)フォームにボタンを置き、キャプション(ボタンの上の表示されるテキスト)を入力し、OnClickイベントハンドラをこのButton1に作らなければならない。
これを行うためボタンを選択(一度クリックする)し、オブジェクトインスペクタで、プロパティ -> Caption、「Open Form2」と入力する。

Objektinspektor.png

2つ目のフォーム(Form2)をプロジェクトに加えるため、メインメニューで ファイル -> 新規フォームを実行する。Form2にボタンを置きそれにOnClickイベントを作る。このボタンのキャプションを「Close」に変更する。

いま、このプロジェクトは2つのフォームを持ち、それぞれはメインメニュー、プロジェクト -> フォーム...(もしくはキーの組み合わせ Shift + F12)で選択、表示できる。また別に、ソースエディタでUnitタブで選択もでき、F12でコードエディタとUnitに割り当てられたフォームデザイナとを切り替えできる。

source code editorUnit (Unit1)が割り当てられたForm1に行きUsesに節「Unit2を加える:

uses
  Classes, SysUtils, ... , Unit2;  // それぞれのユニットがコンマ(,)で区切られていることと
                                   // uses 節がセミコロン(;)で終わることは重要である。

今、Unit2(即ちForm2)をUnit1から呼び出すことができる。

次に、Form1に属するボタンのOnClickイベントを編集する:

unit Unit1;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.ShowModal;  //Form2を表示、フォーカスはForm2に来る。
end;
unit Unit2;
...
procedure TForm2.Button1Click(Sender: TObject);
begin
  Close;  //Form2を閉じる
end;

これで、プロジェクトを起動(Start.png もしくは F9)し、Form1のボタンをクリックすることでForm2を開くことができる。

ShowとShowModalの違い

Showおよび ShowModalメソッドは双方ともフォームを見えるようにする。ShowShowModalの違いを見るために:

  • 前の例、Form1The use of a second formに2番目のTButtonを加え拡張する。
  • Button1を選択しプロパティNamebtnShowに、CaptionShowに変更する。
  • Button2を選択しプロパティNamebtnShowModalに、CaptionShowModalに変更する。
  • OnClickイベントを作る(もしくは、変更)し2つのボタンのイベントハンドラを以下のようにする:
procedure TForm1.btnShowClick(Sender: TObject);
begin
  Form2.Show;
  ShowMessage('Form2 is opened!');
end;

procedure TForm1.btnShowModalClick(Sender: TObject);
begin
  Form2.ShowModal;
  ShowMessage('Form2 is opened and closed again!');
end;
  • 起動してその差を見よう!
Show

このプロシージャはフォームを見える状態にし、呼んだコントロール(Form1)のコードの実行を継続する。この例ではメッセージ、(ShowMessage) はほとんどForm2と同時に現れる。またForm1を呼んで使い続けることができる。例えばそれを動かしたり、Showボタンを押すことができる(しかしShowModalをクリックするとエラーが発生するだろう)。

<myForm>.Show;を用いる代わりに、<myForm>.Visible:=True;を用いることもできる、Showメソッドは以下を行う:

procedure TCustomForm.Show;
begin
  Visible := True;
  BringToFront;
end;

<myForm>.Show;<myForm>.Visible:=True;の唯一の違いは、Showを用いてフォームを表示すると、現在表示されているすべての他のフォームの上に表示されることである。

ShowModal

ShowModalは新しく開かれているフォーム(Form2)が閉じられるまで呼び出したコントロール(Form1)を停止させる。例では、ShowModalの直後のShowMessage行はForm2が閉じた後にのみ実行される。フォームの呼び出しは固まってしまう;Form1を動かすこともそれが持つどのボタンも押すことができない。

ShowModalは整数値の結果を返す関数である。TModalResultを参照のこと。返された値によりどのようにフォームを閉じたかを分岐できる。

お互いを呼び出す2つのフォーム

It is generally good program design to avoid calling the main form from a second form. It is better to return to the main form by closing the second form (as in the previous example) and letting focus revert to the main form. It is, however, possible to call the main from from a sub-form, as this example will show.

In order for Form1 to call Form2, Unit1 must have Unit2 in its Uses clause. Conversely, for Form2 to call Form1, Unit2 must have Unit1 in its Uses clause. This leads to a potential Circular Unit Reference compiler error, with each Unit referring to the other. This example also shows how to avoid the Circular Unit Reference error.

To set up this example, either modify the forms from the previous example (The Use of a Second Form), or create a new project with two forms, each having a single button. Set the caption of Form1.Button1 to "Open Form2", and set the caption of Form2.Button1 to "Open Form1".

If you are modifying the previous example, remove "Unit2" from the Uses clause in Unit1.

Add a Uses clause to the Implementation section of each Unit. Add Unit2 to the Unit1 clause, and add Unit1 to the Unit2 clause, as below:

unit Unit1;
...
implementation

uses
  Unit2;  
...
unit Unit2;
...
implementation

uses
  Unit1;  
...

Now change the code located behind the OnClick event of the button event handler:

unit Unit1;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.Show;  
end;
unit Unit2;
...
procedure TForm2.Button1Click(Sender: TObject);
begin
  Form1.Show; 
end;

他のフォームに変数を渡す

In accordance with the above example The Use of a Second Form, it is possible to declare a global variable in the interface part of Unit2. This would allow access in both Unit1 and Unit2 to one and the same variable (This is because by putting Unit2 in the Uses clause of Unit1, all variables declared in the interface part of Unit2 are also available in Unit1). This practice should be limited to a minimum, as it quickly becomes difficult to remember which individual variables are in scope, potentially increasing errors. It is better to use local variables, define a Property in a Class or, alternatively, as a variable in a class.

In the next project, a second form is opened by clicking on the button. In this case, in the unit of the main form is counted how often the second shape has been shown. In this second form you can ask to see by clicking on the button, how often it has been opened:

  • a new project with two forms, each a button on it and their OnClick events to evaluate.
  • now, in the public part of the Class TForm2 (Unit2) a variable (in this case a constant, which we defined as variable abuse) of type integer with the name Count create:
unit Unit2;
...
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    const Count: Integer = 0;   //here
  end;
  • now even customize the Button event handler accordingly:
unit Unit1;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
  inc(Form2.Count);  //Increase the counter by 1 on each call to Form2
  Form2.ShowModal;   
end;
unit Unit2;
...
procedure TForm2.Button1Click(Sender: TObject);
begin
  ShowMessage('Form2 would be displayed '+IntToStr(Count)+' times');
end;

In this way you can in Unit1 access all public variables/properties/functions/procedures (general methods) of Unit2.

他のフォールに関する事柄

他のフォームをメインフォームとして使う

If you determine after a while that you want to have displayed rather a different form or new form for the view at startup, you can under the main menu Project -> Project Options -> Forms:

Projekteinstellungen Formulare.png

Alternatively, you can display, in Mainmenu -> Project -> Show .lpr file, that Project.lpr (Pascal code of the main program) and create the first form to be displayed as the first:

program Project1;
...
  Application.CreateForm(TForm2, Form2);  //Form2 is created in first and shown when the application starts
  Application.CreateForm(TForm1, Form1);

プログラムの終わりで形のプロパティを保存する

動的にフォームを作るGenerate the form dynamically

Lazarusによってデザインされたフォームを動的に作る

You do not have to create all the forms that may be called during the term of an application at startup. Some developers generally keep none of it and delete the code automatically created when you insert a new form in a project from the Projekt.lpr out immediately. If you want to write a library that contains a couple of GUIs, you can not get around the dynamic creation of forms.

An example:

  • new application with two forms, Form1 a button (add "Unit2" in the uses clause of unit1)
  • open the Projekt.lpr (Project -> lpr file.)
  • delete the line "Application.CreateForm(TForm2, Form2);"
  • in the OnClick event of Button1, Form1 add following code:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2:=TForm2.Create(Nil);  //Form2 is created
  Form2.ShowModal;            //Form2 is displayed
  FreeAndNil(Form2);          //Free Form2 
end;
  • now simply start

新しいフォームを動的に作り出す

The following example will demonstrate how new forms can be generated in code, without using the Form Designer,.

In this example clicking a button should open another form that itself contains a button. Clicking this second button makes a message appear warning that the form will close; then the form is closed.

  • Create a new application with a form and a button
  • In the OnClick event of Button1, in Form1, add the following code:
procedure TForm1.Button1Click(Sender: TObject);
var
  MyForm: TForm;
  MyButton: TButton;
begin
  MyForm:=TForm.Create(nil);             
  MyForm.SetBounds(100, 100, 220, 150);  
  MyForm.Caption:='My dynamic created form';

  MyButton:=TButton.create(MyForm);  
  MyButton.Caption:='Close my form';
  MyButton.SetBounds(10, 10, 200, 30);
  MyButton.Parent:=MyForm;

  MyButton.OnClick:=@MyButtonClick;     

  MyForm.ShowModal;                     

  FreeAndNil(MyForm);     
end;
Light bulb  Note: If a component has been created with an owner (TButton.Create(Owner: TComponent)), it belongs to the owner, who is then responsible to free the component. Thus MyButton is freed automatically by freeing MyForm.
  • now the event handler for MyButton.OnClick must be created. To this end, write in the private section of class TForm1 the following procedure declaration:
TForm1 = class(TForm)
...
private
  { private declarations }
  procedure MyButtonClick(Sender: TObject);
  • press Ctrl]+ Shift+C (code completion) and insert the following code as the handler implementation:
procedure TForm1.MyButtonClick(Sender: TObject);
begin
  Showmessage('Attention, closing my dynamically created form!');
  if Sender is TButton then
    TForm(TButton(Sender).Parent).Close;
end;
  • now the project can be compiled and executed

以下も参照のこと