====== 最初のプログラム Hello World ======
[[lazarus:|{{:lazarus:lazarus_logo.png?150|Lazarus Logo}}]]
このページでは画面にHello World!と表示するだけの簡単なGUIプログラムを作成します。
===== 前提 =====
読み進める前にLazarusのインストールが完了している必要があります。
Lazarusのバージョンはここでは4.0を使用しますが、3.xやそれより古い2.xであっても今の段階ではほとんど違いはありません。
===== プログラムの仕様 =====
一口に「Hello World!と表示する」といっても、GUIアプリケーションではいろいろな形態が考えられますので、もう少し具体的に仕様を決めておきます。
* プログラムを実行されたらウィンドウが表示する。
* ウィンドウにはボタンを一つ配置する。
* ボタンをクリックすると、Hello World!のテキストが含まれるポップアップメッセージを表示する。
次の画像は実際に動作している完成品です。
[{{:lazarus:lazarus_ide_helloworld_1.png|Hello Worldプログラムの実行画面}}]
===== プロジェクトの作成 =====
まずはLazarus IDEを起動します。
IDEが起動すると次のいずれかの状態になっていることが考えられます。
* ①自動で作成された新規プロジェクトがオープンされている。この場合プロジェクト名がproject1となっている。
* ②前回のIDEの終了時のプロジェクトがオープンされている。
* ③プロジェクトウィザードが表示されている。
プロジェクトの作成をはじめからを体験するために、③のケース以外の場合は一度プロジェクト閉じます。
プロジェクトを閉じるには、メニューの [プロジェクト] -> [プロジェクトを閉じる] を選択します。
すると、プロジェクトウィザードのダイアログが表示されます。
[{{:lazarus:lazarus_ide_project_wizard_1.png|プロジェクトウィザードの最初の画面}}]
ここでは新規作成を選択します。
(([Lazarus を終了] を選択した場合、次回のIDE起動時にプロジェクトウィザードが表示されます。③の状態になるのはこのケースです。))
すると、プロジェクト種類を選択する画面に移ります。
[{{:lazarus:lazarus_ide_project_wizard_2.png|新規プロジェクトの種類を選択する画面}}]
ここでは [アプリケーション] を選択します。
すると「project1」という仮の名前がつけられたプロジェクトが作成されます。
このプロジェクトの状態は、IDE起動時に自動で作成される新規プロジェクトと同じです。
つまり、先の①の場合と同じ状態です。
①の場合はそのままそれを流用することができたのですが、自分でプロジェクトを作成する手順を示すためと、説明をしやすくするためにあえてプロジェクトウィザードを経由しました。
===== プロジェクトの保存 =====
新規作成されたプロジェクトproject1はそのままでもビルドして実行できます。
その手順は[[ide-startup-project|IDEの起動と初期プロジェクト]]を参考にしてください。
この場合プロジェクトのファイルは$HOME/tmpというディレクトリに一時的に保存されます。
しかし、このままではIDEを終了して次に起動したとき、変更が維持されていることは保証されません。
なので、まずはプロジェクトを保存する必要があります。
プロジェクトを保存するには次のいずれかの操作を行います。
* メニューの [ファイル] -> [保存] を選択する。
* ショートカットキー Ctrl+S を押す。
するとよく見るファイル保存のダイアログが表示されます。
[{{:lazarus:lazarus_ide_save_project_dialog_1.png|プロジェクトファイルの保存のダイアログが表示された最初の状態}}]
自動でプロジェクトのためのフォルダが作成されることはありません。
面倒ですが、手動でフォルダを作成しながらプロジェクトのルートとなる場所を用意する必要があります。
[{{:lazarus:lazarus_ide_save_project_dialog_2.png|フォルダの作成を繰り返してプロジェクトのルートとなる適切な場所が用意する。保存するファイル名はHelloWorld.lpiに変更する。}}]
プロジェクトを格納するフォルダが用意できたら、あらかじめ入力されている「project1.lpi」という名前を「HelloWorld.lpi」に変更して保存ボタンをクリックします。
保存するプロジェクトファイル(.lpiファイル)の名前の、「HelloWorld」の部分がプロジェクト名として使われます。
この名前はメニューの [プロジェクト] -> [プロジェクトオプション] からいつでも変更可能です。
ただし、プロジェクト名を変更してもlpiファイルの名前までは変わりません。
続けて、Object Pascalのソースコードを保存のダイアログが表示されます。
[{{:lazarus:lazarus_ide_save_project_dialog_3.png|Object Pascalのソースコードを保存するダイアログ}}]
ここでは先のプロジェクトファイルを保存したのと同じフォルダに保存します。
あらかじめ入力されている「unit1.pas」という名前を、適切な名前に変更して保存をクリックします。
今回は「unit1.pas」という名前をそのまま使うことにします。
これで新しく作成したプロジェクトの保存は完了です。
他の多くのIDEが採用している新規プロジェクトの作成のステップは、新規作成時にプロジェクトを置く場所を決めるものです。
プロジェクトが作成された時点ですでにプロジェクト全体が保存された状態になっています。
Lazarus IDEはそうではないので、しばらくは違和感を覚えるかもしれません。
慣れてしまえばどうということないかと思います。
===== プログラムの編集 =====
ここからはIDEを操作しながらプログラムを作成していきます。
==== 初期状態のフォーム ====
新規プロジェクトにはForm1という名前のフォームが一つ含まれています。
もし他のウィンドウに隠れてしまっていたり、閉じてしまった場合、F12キーを押すことで最前面に表示できます。
[{{:lazarus:lazarus_ide_form_editor_empty.png|初期状態のフォーム}}]
このフォームは、マウスで部品を配置したりしたりすることができます。
この編集可能なフォームのことを**フォームエディタ**と呼ぶことにします。
フォームエディタによって手早く直感的なGUIのデザインが可能になっています。
この初期状態のフォームは、プログラムを実行したときに最初に表示されるメインフォームです。
あるいは、ウィンドウシステムの用語を使うならメインウィンドウです。
実行中のプログラムでこのメインフォームを閉じると、プログラムが終了します。
この初期状態のフォームは、新規プロジェクトに含まれるunit1.pas((プロジェクトの保存のときに別の名前で保存していたら、そのファイル名に読み替えてください。))というObject Pascalのソースコードと結びつけられています。
unit1.pasにはユニット名というものがあります。
その名前はファイル名から拡張子を除いたものでなければならず、この場合Unit1です。
((Pascal言語は大文字小文字を区別しないので、unit1でもUnit1でも大丈夫です。))
手を加えていないUnit1のコードは次のようになっています。
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs;
type
TForm1 = class(TForm)
private
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
end.
フォームに変更を加えたり、画面左に表示されているオブジェクトインスペクタからプロパティの値を変更したりすると、連動してこのソースコードにも変更が入ります。
Unit1のコードは、クラシックなオブジェクト指向を基本とするものです。
決して斬新でもクレバーでもないし、多くのアプリケーションフレームワークでみかけるパターンに類似していて親しみやすいものです。
Pascal言語とオブジェクト指向プログラミングの経験さえあれば容易にどのような意味を持つのか推測ができます。
しかし、それらの経験がなければかなり理解しづらいかもしれません。
本来ならコードのすべての部分について丁寧な解説を加えるべきですが、Lazarusの方に注力するためと煩雑になるのを避けるため、このチュートリアルではPascal及びObject Pascalの言語についての解説はしない予定です。
もし機会があれば別のところでFreePascalを用いたプログラミング入門なんかを書いてみたい問気持ちが若干あります。
==== ボタンを配置する ====
まずはこのフォームにボタンを配置してみましょう。
ボタンやその他のGUI部品は**コンポーネント**と呼ばれます。
Lazarusの提供する利用可能なコンポーネントは、IDEのツールバーにあります。
このツールバーは**コンポーネントパレット**と呼ばれます。
ボタンを配置したいので、コンポーネントパレットでボタンのアイコンをクリックします。
[{{:lazarus:lazarus_ide_component_palette_button_1.png|コンポーネントパレットのボタンコンポーネント}}]
次にフォームエディタでの適当な位置をクリックして、そのままドラッグしながら適当なサイズにします。
[{{:lazarus:lazarus_ide_form_editor_button_dragging_size.png|フォームエディタでボタンのサイズを調整中}}]
マウスボタンを離してドラッグを終了すると、フォームにボタンが配置されます。
ボタンのラベルは「Button1」となっています。
[{{:lazarus:lazarus_ide_form_editor_button_placed.png|フォームエディタに配置されたボタン}}]
ボタンを配置するとUnit1にも変化が見られます。
unit Unit1;
...
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton; { これが追加された! }
private
public
end;
...
この状態でプログラムを実行すると、フォームにボタンが表示されます。
ただし、まだクリックしても何も起きません。
==== ボタンがクリックに反応するようにする ====
目標とするアプリケーションの仕様は、ボタンがクリックされたときにポップアップメッセージを表示するものです。
それを実現するためには、ボタンをクリックしたときに何かしらの処理が実行されなければなりません。
ここで、実行される処理とはメソッドです。
ボタンがクリックされるとアプリケーションフレームワークからUnit1のフォームに向けて通知が送られてきます。
その通知は**イベント**と呼ばれます。
ボタンのクリックのイベントはOnClickと名前が決められています。
OnClickイベントに対して、ユーザーが自由に記述できるメソッドを結びつけることができれば目的を達成できます。
イベントを処理するメソッドは**イベントハンドラ**と呼ばれます。
ボタンのOnClickイベントにイベントハンドラを設定する最も簡単な方法は、フォームエディタでボタンをダブルクリックすることです。
そのようにすると、Unit1にイベントハンドラに設定された空のメソッドのコードが追加されます。
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
HelloButton: TButton;
procedure Button1Click(Sender: TObject); { これが追加された! }
private
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
{ これが追加された! }
procedure TForm1.Button1Click(Sender: TObject);
begin
end;
{ 中身は空の状態 }
end.
==== ポップアップメッセージを表示する ====
ここまで来たらあとは簡単です。
Lazarusにはポップアップメッセージを表示するためのプロシージャが用意されています。
いくつかバリエーションがある((参考: https://wiki.freepascal.org/Dialog_Examples))のですが、もっとも単純なものはShowMessageという名前のプロシージャです。
...
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Hello, Lazarus World!'); { これを追記する }
end;
...
ここまでやったところで、一度プロジェクトをビルドして実行しておくとよいでしょう。
[{{:lazarus:lazarus_ide_helloworld_2.png|プログラムを実行してボタンをクリックしたところ}}]
==== ボタンのプロパティ ====
あと残っている仕事は、ボタンのラベルを変更することです。
日本語も使えることを確認するために、「こんにちは」というラベルに変更してみます。
Lazarusの各コンポーネントのオブジェクトは**プロパティ**と呼ばれる様々な値を保持しています。
ボタンの場合はラベルもプロパティによって保持されています。
これまでラベルと呼んできましたが、プロパティの項目名はCaption(キャプション)です。
現時点でボタンのラベルが「Button1」と表示されているのは、Captionプロパティに「Button1」と設定されているからです。
プロパティを変更するのは、(通常は)画面の左側に表示されている**オブジェクトインスペクタ**から行います。
オブジェクトインスペクタで目的のプロパティを見つけるには次のステップを踏みます。
- フォームエディタでボタンをクリックする。もしくはオブジェクトインスペクタの上部にあるコンポーネントでボタンを選択する。
- オブジェクトインスペクタのプロパティタブからCaptionという項目を探す。もしくはフィルタのところにCaptionと入力して検索する。
次の図はCpationプロパティを変更したところです。
[{{:lazarus:lazarus_ide_object_inspector_button_caption.png|オブジェクトインスペクタでCaptionプロパティを変更する}}]
この時点でフォームエディタのボタンのラベルに反映されて「こんにちは」に変わっています。
[{{:lazarus:lazarus_ide_form_editor_button_caption_changed.png|フォームエディタのボタンのラベルが「こんにちは」に変わったところ}}]
[[install#fcitx5を利用している場合の注意|インストール]]のところでLazarus IDEとFcitx5には相性問題があると書きました。
少し奇妙な感じがしますが、ソースコードエディタ以外のところではおおよそ問題なく日本語の入力が可能です。
しかし、絶対に大丈夫とは言い切れないところもあり、もしかしたら環境によってはここでも入力できない場合があるかもしれません。
不幸にも入力できなかった場合は、別のテキストエディタなど入力したテキストをコピーして、Lazarus IDEの方にそれを貼り付けるなどの対策が考えられます。
=== ボタンの名前の変更 ===
ここでもう一つ重要なプロパティを変更します。
ほとんどのコンポーネントにはNameというプロパティがあります。
このプロパティを変更すると、そのプロパティを識別する名前が変わります。
どういうことかというと、先程「Button1」のCpationを「こんにちは」に変えました。
ボタンの表示は「こんにちは」に変わりましたが、ボタンそのものの名前はまだ「Button1」のままです。
この「Button1」という名前はソースコードに現れています。
...
TForm1 = class(TForm)
Button1: TButton; { ここでButton1という名前が使われている }
procedure Button1Click(Sender: TObject); { ここでも使われている }
private
public
end;
...
...
procedure TForm1.Button1Click(Sender: TObject); { ここでも使われている }
begin
ShowMessage('Hello, Lazarus World!');
end;
...
今作成しているような小さなプログラムでは何も問題はありません。
しかし、プログラムの規模が大きくなったら読みにくくなることは間違いありません。
何より美しくないです。
オブジェクトインスペクタのプロパティのNameを変更すると、ソースコードもその名前に合わせて変更してくれます。
実際にNameを「Button1」から「HelloButton」に変更してみます。
すると、ソースコードが自動で更新されて次のようになります。
...
TForm1 = class(TForm)
HelloButton: TButton; { Button1からHelloButtonになった }
procedure HelloButtonClick(Sender: TObject); { Button1ClickからHelloButtonClickになった }
private
public
end;
...
...
procedure TForm1.HelloButtonClick(Sender: TObject); { Button1ClickからHelloButtonClickになった }
begin
ShowMessage('Hello, Lazarus World!');
end;
...
==== フォームのプロパティ ====
最後に、メインフォームのプロパティも変更しておきます。
メインフォームにもCaptionプロパティとNameプロパティが存在します。
* Captionは、設定したテキストが実行時のウィンドウのタイトルになります。
* Nameは、このフォームコンポーネントを識別する名前です。
ボタンのときと同じようにしてCaptionとNameの値を変更します。
オブジェクトインスペクタでForm1を選択するか、フォームエディタでフォームのどこか(ボタンではないところ)をクリックすると、Form1のプロパティが表示されます。
そこで次の変更を加えます。
* Captionを「Form1」から「My First App」に変更します。
* Nameを「Form1」から「MyForm」に変更します。
変更が終わると、ソースコードが更新されます。
最終的にUnit1の内容は次のようになります。
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TMyForm }
TMyForm = class(TForm)
HelloButton: TButton;
procedure HelloButtonClick(Sender: TObject);
private
public
end;
var
MyForm: TMyForm;
implementation
{$R *.lfm}
{ TMyForm }
procedure TMyForm.HelloButtonClick(Sender: TObject);
begin
ShowMessage('Hello, Lazarus World!');
end;
end.
この時点でプログラムを実行すると、最初に提示したプログラムの実行画面と同じ結果が得られます。
これで完成です。
===== お疲れ様でした! =====
予定していたよりずっと多くの分量になってしまいました。
もし最初から順番に追いかけてやってきていたとしたら、結構大変な仕事だったと思います。
なぜこんな簡単なプログラムのためにこんなに多くのことをやらないといけないんだ、と疑問に思われるかもしれません。
これだけ多くなってしまったのは、必要なIDEの使い方を逐一取り上げて説明を加えていったからです。
もしそれらについてすでに知っているなら、大幅に簡略化できます。
慣れてしまえばこのページで作成した程度のプログラムなら、数分足らずで作ることができるようになります。
IDEを利用したプログラミングは、最初の取っ掛かりに時間がかかるのが厄介です。
一方で、一度基本を身につけてしまえば、その応用によって新たな機能を覚えるのにあまり時間はかからなくなっていきます。
このページで学んだことが十分な基本となっているかどうかはわかりませんが、今後のIDEの使用において何らかの助けになれば幸いです。