課題
作成するプログラムは次のようなインタフェイスを備えているものとします.
- カレンダー表示欄
上部のボタンで年・月を切り替えられる. また表示されているカレンダーで日付を押して選択できる.
# 既存のCalendarウィジェットをそのまま利用可能 - 情報表示(入力)欄
文字で情報を表示(あるいは入力)できる. - 終了ボタン
このボタンを押すとプログラムを終了する.
作成するプログラムでは,カレンダー表示欄で選択された日が 祝日であるときには「情報表示欄」にその祝日の名称を表示して, 祝日でないときには何も表示しないことにします.
祝日として,日本の祝日を扱う必要はありません. 架空の祝日を設定して構いません. 祝日は毎年固定であるとして,成人の日,春分の日などのように 年によって移動しうる祝日に対応する必要はありません. 要するにプログラム内で記述した(適当な)祝日のデータに従って, カレンダーで情報が表示できればよいことにします.
[option] スケジュール機能について
スケジュール機能をもたせる場合には,情報表示欄を入力欄としても利用します. 入力するスケジュールは日付ごとに1行のみとします. 日付を指定して,スケジュールを入力すると, その日が選択されるたびに,当該のスケジュールを表示することにします.
さらにスケジュールデータを(適当な名前の)ファイルに保存して, プログラムが実行開始されたときに,そのファイルに保存されている スケジュールをすべて読み込むこと,また プログラム終了時には,保持されているスケジュールデータを すべてファイルに保存することができるとよいでしょう.
スケジュール機能を実現する場合,祝日の名称表示は実現しなくても構いません. できるなら両方を(一つのプログラムとして)実現してみてください. その場合,祝日にスケジュールが登録されていたら,「祝日の名称」に続いて,スケジュールを表示することにします.
もくじ
- プログラムヘッダ(GUIライブラリの読み込み)
- ウィジェットによるGUIの構築
- GUIプログラムの基本構成
- さまざまなウィジェットとメソッド(コールバックを含む)
- ウインドウの表示とイベントループ開始
- サンプルプログラム
- 参考情報
プログラムヘッダ(GUIライブラリの読み込み)
次に示すコードをプログラムの先頭にコピーして入れておくようにしてください(必要事項は記入してください).
=begin 所属: 氏名: 学生番号: 難易度(5段階評価): 感想など(任意) =end # Gtk2(GUIライブラリ)を読み込む require 'gtk2'
ここでrequireしているGtk2は代表的なGUIライブラリの一つです. タートルグラフィクスもGtk2を使って作成しています.
ウィジェットによるGUIの構築
GUIはウィジェット(Widget)を組み合わせて構築します. 基本要素として次のようなものがあります.
- トップレベルウインドウ
すべてのウィジェットの土台となります. すべてのウィジェットはトップレベルウインドウの配下に設置されます.
- コンテナウィジェット
他のウィジェットを格納して配置するためのウィジェットです. コンテナ自体は表示されない場合もあります. 左図の例では,VBox(Vertical Box)とHBox(Horizontal Box)がコンテナです. 図ではVBoxには上から順に縦方向に3つのウィジェットが格納されていることを示しています.
MenuBar
Text Display Area
HBox
さらにHBoxには2つのボタンが格納されていることを示しています. このようにコンテナウィジェットを入れ子にして配置することで,さまざまなレイアウトを実現できます. なおVBoxはトップレベルウインドウに格納されています.
- 機能ウィジェット
ボタン,メニュー,情報表示等々の機能のインタフェイスを提供するウィジェットです.
GUIプログラムの基本構成
ここではGUIプログラムの基本構成を説明します. まず次にサンプルプログラム(hello.rb)を示します.
require 'gtk2' # Gtk2 GUIライブラリ # トップレベルウインドウ window = Gtk::Window.new('Hello!') # 引数はウインドウのタイトル window.signal_connect('destroy') { Gtk.main_quit } # 終了処理 window.signal_connect('delete_event') { false } # タイトルバーの[×]ボタンの処理 # 縦方向パッキングボックス vbox = Gtk::VBox.new vbox.set_border_width(10) # vboxの周囲のスペースの広さ vbox.set_spacing(10) # vboxの要素の間のスペースの幅 # メッセージ表示ラベル msg = Gtk::Label.new(' Hello, world! ') # [Quit]ボタン(押されたら終了) qbutton = Gtk::Button.new(Gtk::Stock::QUIT) # Stockを貼り付けたボタン # ボタンがクリックされたときのコールバック qbutton.signal_connect('clicked') do window.destroy # トップレベルウインドウを閉じて終了する end # レイアウト vbox.pack_start(msg) # msgをボックスの先頭から入れる vbox.pack_start(qbutton) # qbuttonをボックスの先頭から入れる window.add(vbox) # vboxをwindowに入れる # 実行開始 window.show_all # ウインドウの表示 Gtk.main # イベントループ
プログラムは3つに分けることができます.
- 各ウィジェットの定義(コールバックの定義も含む)
- レイアウト(ウィジェットの配置)
- 実行開始(ウィジェット表示とイベントループの開始)
最初にトップレベルウィンドウ,コンテナをはじめとする各種のウィジェットを一通り定義します. このときプログラムで処理するイベントに対応するコールバックも定義します. 次に各ウィジェットをコンテナウィジェットを組み合わせて配置します. ここまでで準備は終了です. 最後にウィジェットを表示してイベントループを開始します. これによりGUIが表示され,イベント処理が開始されます.
なおこのプログラムのGUIは次のようなウイジェットで構成されています.
window(トップレベル) -- vbox(コンテナ) --+-- msg(ラベル)
|
+-- qbutton(ボタン)
さまざまなウィジェットとメソッド(コールバックを含む)
ここでは課題のプログラムで利用する可能性のある各種ウィジェット, 設定のためのメソッド(コールバック)を示します. コールバックは処理するイベントごとに定義します.
- トップレベルウインドウ
すべてのウィジェットの土台となるウインドウです. 次のように作成し,プログラム終了のためのイベント処理を定義しておきます.window = Gtk::Window.new('タイトル') # 引数はウインドウのタイトル window.signal_connect('destroy') { Gtk.main_quit } # 終了処理 window.signal_connect('delete_event') { false } # タイトルバーの[×]ボタンの処理 - パッキングボックス
コンテナウィジェットです. 縦方向にウィジェットを並べて格納するVBoxと 横方向にウィジェットを並べて格納するHBoxが使えます. トップレベルウインドウにVBoxを入れて,そのVBoxの中にウィジェットを順に格納していくのがGUI構築の基本パターンです.window = Gtk::Window.new('タイトル') vbox = Gtk::VBox.new vbox.set_border_width(10) # vboxの周囲のスペースの広さ vbox.set_spacing(10) # vboxの要素の間のスペースの幅 window.add(vbox) # windowにvboxを格納するパッキングボックスにウィジェットを格納するには次のメソッドを使います. VBoxの場合,pack_startは上から順にウィジェットを格納します. pack_endは下から順にウィジェットを格納します. HBoxの場合,pack_startは左から順にウィジェットを格納します. pack_endは右から順にウィジェットを格納します. 次に「ラベルウィジェット」を縦に並べる例を示します.label1 = Gtk::Label.new('one') label2 = Gtk::Label.new('two') label3 = Gtk::Label.new('three') # vboxの先頭(上)側にラベルウィジェット1を格納する vbox.pack_start(label1) # vboxの末尾(下)側にラベルウィジェット3を格納する vbox.pack_end(label3) # vboxの先頭(上)側にラベルウィジェット2を格納する vbox.pack_start(label2)この例では上から順にone,two,threeとラベルが並びます. 同様なレイアウトで作成したサンプルを示します. - カレンダーウィジェット
カレンダーの諸機能を提供するウィジェットです. まず次のようにして生成・設定します.calendar = Gtk::Calendar.new # 年月の切替欄と曜日を表示するように設定 calendar.display_options(Gtk::Calendar::SHOW_HEADING| Gtk::Calendar::SHOW_DAY_NAMES)カレンダーの日付は,とくに指示しない限り, 自動的に実行時の日付に合わせて設定されます(特定の日付を指定して生成することもできます). ウィジェットに備わっている機能によって, 年・月の変更,日付の選択ができます.
カレンダーで選択されている日付の年月日を得るには次のようにします.# year=年(西暦) # month=月 # day=日 year,month,day = calendar.date # 年月日を取得
なおウィジェットが作られた時点では最初に設定された日付(とくに指定しなければ現在の日付)が選択されている状態になっています.
カレンダー上で日付が選択されると「day_selected」イベントが発生します. このイベントにコールバックを設定すれば, 日付が選択されたときにコールバックで指定した処理を実行できます.calendar.signal_connect('day_selected') do year,month,day = calendar.date # 年月日を取得 end - テキスト表示・入力ウィジェット
1行のテキスト表示・入力欄を提供するウィジェットです. 次のように記述することで欄内に表示するテキスト(文字列)を設定できます. ウィジェットを表示する前に設定しておくこともできます.# 名称の定義 holiday_name = "元日" entry = Gtk::Entry.new # entryに表示する文字列をholiday_nameとする entry.set_text(holiday_name) # entryに表示する文字列を消す(空の文字列を表示する) entry.set_text('')
次のように記述することで欄内のテキスト(文字列)を取得できます.text = entry.layout.text
activateイベント([Enter]が入力されたときに発生するイベント)にcallbackを指定できます.entry.signal_connect('activate') do end - ボタンウィジェット
ボタンを提供するウィジェットです.clickedイベント(クリックされたときに発生するイベント)にcallbackを指定できます. ボタンには表示する文字列やStock(アイコンやショートカットが定義された部品)を指定できます(※Stockを指定してもアイコンが利用可能でない場合は文字列のみが表示されます).window = Gtk::Window.new('タイトル') cbutton = Gtk::Button.new(' Click me! ') # 文字列を貼り付けたボタン cbutton.signal_connect('clicked') do puts 'Button Clicked!' end qbutton = Gtk::Button.new(Gtk::Stock::QUIT) # Stockを貼り付けたボタン qbutton.signal_connect('clicked') do window.destroy # トップレベルウインドウを閉じて終了する end - ラベルウィジェット
画面に文字列を表示するためのウィジェットです.label = Gtk::Label.new(' Label String ') - フレームウィジェット
タイトル付きの枠を表示するコンテナウィジェットです. 内部に格納したウィジェットの周囲に枠が表示されることになります.hbox = Gtk::HBox.new # 引数はタイトル # 引数を与えなければタイトルを付けずに枠だけ表示する frame = Gtk::Frame.new('Frame Title') frame.add(hbox) # frame内にhboxを格納
ウインドウの表示とイベントループ開始
ウィジェットとコールバックを定義して,ウィジェットを配置して,GUIのすべての準備が終了したら,最後に次の処理によってウインドウを表示して,イベントループを開始します.
# 実行開始 window.show_all # ウインドウ表示(トップレベルウインドウに対して適用する) Gtk.main # イベントループ開始
サンプルプログラム
サンプルプログラムを用意しています. プログラムをブラウザの画面で開いたときに文字化けしてしまう場合には, ダウンロードしてEmacs等で開いてみてください.
- hello.rb
- vbox.rb(VBoxのテスト)
- entry_dialog.rb(EntryとMessageDialogのテスト)
- gtb.rb(ボタンの配置と変更)
- editor.rb(簡易エディタ;編集のみ)
- editor2.rb(簡易エディタ2;編集のみ)
日置尋久(HIOKI Hirohisa)
Last modified: Fri Dec 26 16:50:30 JST 2025