差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
fltk:helloworld [2025/05/30 12:54] – Update code; pass argc and argv to window->show() freemikanfltk:helloworld [2025/06/09 20:19] (現在) – Escape double dash "--" with %% freemikan
行 1: 行 1:
-====== ボタン ====== +====== Hello World ====== 
-{{:fltk:fltk_shadow.png?200|FLTK}}+[[fltk:|{{:fltk:fltk_shadow.png?200|}}]]
  
 +このページでは、FLTKを利用した小さなプログラムを作成します。
 +C++コードの内容を理解することよりも、ビルド(コンパイルとリンク)のやり方を理解することに重点を置きます。
 +まずはコマンドラインから手動でGCCのコマンドを実行する方法を紹介します。
 +この方法さえを理解してしまえば、Makefileを書くにもIDEの設定を行うにもに苦労せずにすむかと思います。
 +===== 前提 =====
 +[[install|FLTKのインストール]]に従って、FLTK 1.4.3が $HOME/MikanBox 以下にインストールされているものとします。
 +違う場所にインストールした場合は((違う場所であっても全く問題ありません。))、パスをご自身のものに置き換えてください。
  
-===== Fl_Buttonクラス ===== 
  
-Fl_Buttonラスから派生するス全体階層図+===== 作業ディレトリの用意 ===== 
 +作業ディレクトリは $HOME/code/fltk/hello-fltk とします。 
 +ここに作成するプログソースコードを保存して、また、ここでビルドを行います。
  
-{{ https://www.fltk.org/doc-1.4/classFl__Button.png | Fl_Buttonクラス前クラス階層図 }}+<note> 
 +こういった名前やパは、何かしら決めておかないと説明がしづらいので提示しているだけです。 
 +同じ名にする必要は全くありません。 
 +ご自身好みの場所に好きな名前で作成してください。 
 +</note>
  
-{{ :fltk:widget_demo-button1-fl_button.mp4 |Fl_Button demo}}+まずディレクトリを作成して、そこに移動しておきます。
  
-<code cpp+<cli
-#include <FL/Fl.H> +$ mkdir -p ~/code/fltk/hello-fltk 
-#include <FL/Fl_Button.H> +$ cd $_ 
-#include <FL/Fl_Window.H>+</cli>
  
-int main(int argc, char **argv) { 
-  auto window = new Fl_Window(400, 300, "Fl_Button Demo"); 
-  auto button1 = new Fl_Button(100, 85, 200, 30, "Hello, SMALL world!"); 
-  auto button2 = new Fl_Button(100, 135, 200, 30, "Hello, MEDIUM world!"); 
-  auto button3 = new Fl_Button(100, 185, 200, 30, "Hello, LARGE world!"); 
-  window->end(); 
-  window->show(argc, argv); 
-  return Fl::run(); 
-} 
-</code> 
  
 +===== プログラムのソースコード =====
 +今回作成するプログラムのソースコードは、FLTKのマニュアルにあるものをそのまま拝借します。
  
-==== Fl_Radio_Buttonクラス ====+  * https://www.fltk.org/doc-1.4/basics.html
  
-{{ :fltk:widget_demo-button2-fl_radio_button.mp4 |Fl_Radio_Button demo}}+__main.cpp__:
  
 <code cpp> <code cpp>
-#include <FL/Fl.H> +/********************************************/ 
-#include <FL/Fl_Radio_Button.H> +/* https://www.fltk.org/doc-1.4/basics.html */ 
-#include <FL/Fl_Window.H>+/********************************************/
  
-int main(int argc, char **argv) { 
-  auto window = new Fl_Window(400, 300, "Fl_Radio_Button Demo"); 
-  auto button1 = new Fl_Radio_Button(100, 85, 200, 30, "Hello, SMALL world!"); 
-  auto button2 = new Fl_Radio_Button(100, 135, 200, 30, "Hello, MEDIUM world!"); 
-  auto button3 = new Fl_Radio_Button(100, 185, 200, 30, "Hello, LARGE world!"); 
-  window->end(); 
-  window->show(argc, argv); 
-  return Fl::run(); 
-} 
-</code> 
- 
- 
-==== Fl_Repeat_Buttonクラス ==== 
- 
-{{ :fltk:widget_demo-button3-fl_repeat_button.mp4 |Fl_Repeat_Button demo}} 
- 
-<code cpp> 
 #include <FL/Fl.H> #include <FL/Fl.H>
-#include <FL/Fl_Repeat_Button.H> 
 #include <FL/Fl_Window.H> #include <FL/Fl_Window.H>
 +#include <FL/Fl_Box.H>
  
 int main(int argc, char **argv) { int main(int argc, char **argv) {
-  auto window = new Fl_Window(400300, "Fl_Repeat_Button Demo"); +  Fl_Window *window = new Fl_Window(340180); 
-  auto button1 = new Fl_Repeat_Button(1008520030, "Hello, SMALL world!"); +  Fl_Box *box = new Fl_Box(2040300100, "Hello, World!"); 
-  auto button2 = new Fl_Repeat_Button(100, 135, 200, 30, "Hello, MEDIUM world!"); +  box->box(FL_UP_BOX); 
-  auto button3 = new Fl_Repeat_Button(100, 185, 200, 30, "Hello, LARGE world!");+  box->labelfont(FL_BOLD + FL_ITALIC); 
 +  box->labelsize(36); 
 +  box->labeltype(FL_SHADOW_LABEL);
   window->end();   window->end();
   window->show(argc, argv);   window->show(argc, argv);
行 69: 行 58:
 </code> </code>
  
 +かなり直感的なものであるとは思います。
 +もしそうでなくて意味不明だったとしても、問題ありません。
 +このコードを素材に、FLTKアプリケーションのビルド手順を体験するのが今回の目的です。
 +コードの意味については今後よく吟味します。((さしあたってnewによって作成したオブジェクトをdeleteしていないことに疑念を抱かれかるもしれませんが、これが現実で問題になることはありません。FLTKはそのように作られています。))
  
-==== Fl_Return_Buttonクラス ====+===== コンパイル ===== 
 +コンパイルとリンクを一度に行うこともできますが、今回は別々に分けて行います。 
 +そのほうが説明しやすいからです。
  
-{{ :fltk:widget_demo-button4-fl_return_button.mp4 |Fl_Return_Button demo}}+FLTKには、fltk-configというツール((シェルスクリプトで書かれたユーティリティです。))が付属しています。 
 +pkg-configによく似た使い方をします。 
 +$HOME/MikanBoxにFLTKをインストールしたので、この下のbinディレクトにfltk-configが存在しています。
  
-<code cpp+<cli
-#include <FL/Fl.H> +$ ~/MikanBox/bin/fltk-config --version 
-#include <FL/Fl_Return_Button.H> +1.4.3 
-#include <FL/Fl_Window.H>+</cli>
  
-int main(int argc, char **argv) { +このツールは、指定されたオプションにしたがって、コンパイラ・リンカに渡すフラグをテキストとして出力します。 
-  auto window = new Fl_Window(400, 300, "Fl_Return_Button Demo"); +指定可能なオプションの一覧は[[fltk-config-help|こちら]]。
-  auto button1 = new Fl_Return_Button(100, 85, 200, 30, "Hello, SMALL world!"); +
-  auto button2 = new Fl_Return_Button(100, 135, 200, 30, "Hello, MEDIUM world!"); +
-  auto button3 = new Fl_Return_Button(100, 185, 200, 30, "Hello, LARGE world!"); +
-  window->end(); +
-  window->show(argc, argv); +
-  return Fl::run(); +
-+
-</code>+
  
 +C++コンパイラに指定するコンパイルフラグを出力するためのオプションは「%%--%%cxxflags」です。
  
-==== Fl_Toggle_Buttonクラス ====+<cli> 
 +$ ~/MikanBox/bin/fltk-config --cxxflags 
 +-I/home/freemikan/MikanBox/include -I/home/freemikan/MikanBox/include/FL/images -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_THREAD_SAFE -D_REENTRANT 
 +</cli>
  
-{{ :fltk:widget_demo-button5-fl_toggle_button.mp4 |Fl_Toggle_Button demo}}+パスのプリフィクスが/home/freemikan/MikanBoxとなっていることに注目してください。 
 +これはインストール時にCMAKE_INSTALL_PREFIXでそう指定したからこのようになっています。
  
-<code cpp> +C++コンパイラとしてGCCを利用するので、この出力をそのままg++コマンドに渡してやります。 
-#include <FL/Fl.H> +コピペするより、シェルのコマンド置き換えを利用したほうがずっと良いです。 
-#include <FL/Fl_Toggle_Button.H> +コマンド置き換えは ''$(//command ...//)'' とするか ''`//command ...//`''((「`」はバッククォートです)) とします。 
-#include <FL/Fl_Window.H>+具体的には次のようにしてコンパイルします。
  
-int main(int argc, char **argv) { +<cli
-  auto window = new Fl_Window(400, 300, "Fl_Toggle_Button Demo"); +$ g++ -c main.cpp `~/MikanBox/bin/fltk-config --cxxflags` 
-  auto button1 = new Fl_Toggle_Button(100, 85, 200, 30, "Hello, SMALL world!"); +</cli>
-  auto button2 = new Fl_Toggle_Button(100, 135, 200, 30, "Hello, MEDIUM world!"); +
-  auto button3 = new Fl_Toggle_Button(100, 185, 200, 30, "Hello, LARGE world!"); +
-  window->end(); +
-  window->show(argc, argv); +
-  return Fl::run(); +
-} +
-</code>+
  
 +「-c」は手動で与えている点に注意してください。
 +これによって、リンクは行わず、コンパイルのみを行うこと指示しています。
  
-==== Fl_Shortcut_Buttonクラス ====+==== 結果の確認 ==== 
 +コンパイラのオプションに間違いがなく、コンパイルエラーもなければ、何もメッセージは出力されずにコマンドが完了します。 
 +コンパイルされたオブジェクトファイルが生成されているはずなので、それを確認してみましょう。
  
-{{ :fltk:widget_demo-button6-fl_shortcut_button.mp4 |Fl_Shortcut_Button demo}}+<cli> 
 +$ ls -l 
 +合計 12 
 +-rw-r--r-- 1 freemikan freemikan  400  5月 23 01:01 main.cpp 
 +-rw-rw-r-- 1 freemikan freemikan 7816  5月 23 01:01 main.o      ←生成されたオブジェクトファイル 
 +</cli>
  
-<code cpp> +main.oが存在していればOKです。
-#include <FL/Fl.H> +
-#include <FL/Fl_Shortcut_Button.H> +
-#include <FL/Fl_Window.H>+
  
-int main(int argc, char **argv) { +===== リンク ===== 
-  auto window new Fl_Window(400, 300, "Fl_Shortcut_Button Demo"); +リンカオプションも同様にfltk-configの助けを借ります。 
-  auto button1 new Fl_Shortcut_Button(100, 85, 200, 30, "Hello, SMALL world!"); +リンカオプションを出力するfltk-configのオプションは「%%--%%ldflags」です。
-  auto button2 new Fl_Shortcut_Button(100, 135, 200, 30, "Hello, MEDIUM world!"); +
-  auto button3 new Fl_Shortcut_Button(100, 185, 200, 30, "Hello, LARGE world!"); +
-  window->end(); +
-  window->show(argc, argv); +
-  return Fl::run(); +
-+
-</code>+
  
 +<cli>
 +$ ~/MikanBox/bin/fltk-config --ldflags
 +-L/home/freemikan/MikanBox/lib -lfltk -lm -lX11 -lXext -lpthread -ldl
 +</cli>
  
-==== Fl_Light_Buttonクラス ====+これをコマンド置き換えでg++に渡してやります。
  
-Fl_Light_Buttonクラス前後のクラス階層図 +<cli> 
-{{ https://www.fltk.org/doc-1.4/classFl__Light__Button.png |Fl_Light_Buttonクラス前後のクラス階層}}+$ g++ -o hello-fltk main.o `~/MikanBox/bin/fltk-config --ldflags` 
 +</cli>
  
-{{ :fltk:widget_demo-button7-fl_light_button.mp4 |Fl_Light_Button demo}}+-o hello-fltk」は、生成する実行可能バイナリファイル名前をhello-fltkとすることを指示しています。 
 +続けて、入力ファイルであるmain.oを指定しています。
  
-<code cpp+<note
-#include <FL/Fl.H> +入力ファイルmain.oの位置は意味を持ちます。 
-#include <FL/Fl_Light_Button.H> +リンカオプションより後ろにしてはいけません。
-#include <FL/Fl_Window.H>+
  
-int main(int argc, char **argv) { +<cli
-  auto window = new Fl_Window(400, 300, "Fl_Light_Button Demo"); +$ g++ -o hello-fltk `~/MikanBox/bin/fltk-config --ldflags` main.o 
-  auto button1 = new Fl_Light_Button(100, 85, 200, 30, "Hello, SMALL world!"); +</cli>
-  auto button2 = new Fl_Light_Button(100, 135, 200, 30, "Hello, MEDIUM world!"); +
-  auto button3 = new Fl_Light_Button(100, 185, 200, 30, "Hello, LARGE world!"); +
-  window->end(); +
-  window->show(argc, argv); +
-  return Fl::run(); +
-} +
-</code>+
  
-=== Fl_Check_Button ===+これはリンクエラーになります。 
 +</note>
  
-{{ :fltk:widget_demo-button8-fl_check_button.mp4 |Fl_Check_Button demo}} 
  
-<code cpp> +==== 結果の確認 ==== 
-#include <FL/Fl.H> +リンクに問題がなければ、何もメッセージは出力されずにコマンドが終了します。 
-#include <FL/Fl_Check_Button.H> +実行可能バイナリファイルが生成されていることを確認しておきましょう。
-#include <FL/Fl_Window.H> +
- +
-int main(int argc, char **argv) { +
-  auto window new Fl_Window(400, 300, "Fl_Check_Button Demo"); +
-  auto button1 new Fl_Check_Button(100, 85, 200, 30, "Hello, SMALL world!"); +
-  auto button2 new Fl_Check_Button(100, 135, 200, 30, "Hello, MEDIUM world!"); +
-  auto button3 new Fl_Check_Button(100, 185, 200, 30, "Hello, LARGE world!"); +
-  window->end(); +
-  window->show(argc, argv); +
-  return Fl::run(); +
-+
-</code> +
- +
- +
-=== Fl_Radio_Light_Button === +
- +
-{{ :fltk:widget_demo-button9-fl_radio_light_button.mp4 |Fl_Radio_Light_Button demo}} +
- +
-<code cpp> +
-#include <FL/Fl.H> +
-#include <FL/Fl_Radio_Light_Button.H> +
-#include <FL/Fl_Window.H> +
- +
-int main(int argc, char **argv) { +
-  auto window = new Fl_Window(400, 300, "Fl_Radio_Light_Button Demo"); +
-  auto button1 = new Fl_Radio_Light_Button(100, 85, 200, 30, "Hello, SMALL world!"); +
-  auto button2 = new Fl_Radio_Light_Button(100, 135, 200, 30, "Hello, MEDIUM world!"); +
-  auto button3 = new Fl_Radio_Light_Button(100, 185, 200, 30, "Hello, LARGE world!"); +
-  window->end(); +
-  window->show(argc, argv); +
-  return Fl::run(); +
-+
-</code> +
- +
- +
-=== Fl_Round_Button === +
- +
-{{ :fltk:widget_demo-button10-fl_round_button.mp4 |Fl_Round_Button demo}} +
- +
-<code cpp> +
-#include <FL/Fl.H> +
-#include <FL/Fl_Round_Button.H> +
-#include <FL/Fl_Window.H> +
- +
-int main(int argc, char **argv) { +
-  auto window = new Fl_Window(400, 300, "Fl_Round_Button Demo"); +
-  auto button1 = new Fl_Round_Button(100, 85, 200, 30, "Hello, SMALL world!"); +
-  auto button2 = new Fl_Round_Button(100, 135, 200, 30, "Hello, MEDIUM world!"); +
-  auto button3 = new Fl_Round_Button(100, 185, 200, 30, "Hello, LARGE world!"); +
-  window->end(); +
-  window->show(argc, argv); +
-  return Fl::run(); +
-+
-</code> +
- +
- +
-== Fl_Radio_Round_Button == +
- +
-{{ :fltk:widget_demo-button11-fl_radio_round_button.mp4 |Fl_Radio_Round_Button demo}} +
- +
-<code cpp> +
-#include <FL/Fl.H> +
-#include <FL/Fl_Radio_Round_Button.H> +
-#include <FL/Fl_Window.H> +
- +
-int main(int argc, char **argv) { +
-  auto window = new Fl_Window(400, 300, "Fl_Radio_Round_Button Demo"); +
-  auto button1 = new Fl_Radio_Round_Button(100, 85, 200, 30, "Hello, SMALL world!"); +
-  auto button2 = new Fl_Radio_Round_Button(100, 135, 200, 30, "Hello, MEDIUM world!"); +
-  auto button3 = new Fl_Radio_Round_Button(100, 185, 200, 30, "Hello, LARGE world!"); +
-  window->end(); +
-  window->show(argc, argv); +
-  return Fl::run(); +
-} +
-</code>+
  
 +<cli>
 +$ ls -l
 +合計 1644
 +-rwxrwxr-x 1 freemikan freemikan 1670960  5月 23 01:02 hello-fltk   ←生成された実行可能バイナリファイル
 +-rw-r--r-- 1 freemikan freemikan     400  5月 23 01:01 main.cpp
 +-rw-rw-r-- 1 freemikan freemikan    7816  5月 23 01:01 main.o
 +</cli>
  
 +hello-fltkが存在していればOKです。
 +===== Hello Worldプログラムの実行 =====
 +最後に、hello-fltkを実行して、問題なくFLTKのウィンドウが表示されることを確認しておきます。
  
-===== 参照 =====+<cli> 
 +$ ./hello-fltk 
 +</cli>
  
-  * [[https://www.fltk.org/doc-1.4/classFl__Button.html|Fl_Buttonクラスのリファレンス]]+{{ :fltk:fltk_hello.jpg |Hello FLTK!}}
  
 +このようなルック・アンド・フィールは典型的なFLTKアプリケーションのスタイルです。
 +あくまで個人的にですが、ややレトロチックで2000年代初頭のような印象を受けます。
 +逆にそれが良いと思われれば幸いです。
文書の先頭へ