カレンダーを使う

Gtk+ではカレンダーウィジェットというのが用意されているので、今回はこれを使ってみる。

カレンダー上の日付を選択すると、その日付をテキストエリアに表示するという簡単なアプリケーションを作ってみた。

(ソースは以下の場所に置いてあります)
http://github.com/egawata/hatena_blog/tree/master/calendar/

 39     //  GtkCalendar オブジェクトの生成
 40     calendar = gtk_calendar_new();
 41 
 42     //  日付表示用エリア
 43     text = gtk_entry_new();

カレンダーオブジェクトを作成する。ついでに、選択された日付を表示するためのテキストエリアも用意しておく。

 47     g_signal_connect(G_OBJECT(calendar), "day-selected",
 48                      G_CALLBACK(disp_day), (gpointer)text);

GtkCalendar はいくつかのシグナルを扱うことができる が、カレンダー上の日付がクリックされたら何か処理を行いたい、ということはよくあるだろう。そのときは "day-selected" というシグナルが発生する。
上記では、"day-selected" シグナルが発生したときに、disp_day 関数(10-22行)をコールするように指示している。


disp_day 関数は、カレンダー上で選択された日付を、年月日の文字列に直してテキストエリアに表示する処理を行っている。

 10 static void disp_day(GtkCalendar *calendar, GtkEntry *text)
 11 {
 12     guint year, month, day;
 13     gchar ymd[100];
 14 
 15     //  カレンダー上で選択された年月日を得る
 16     gtk_calendar_get_date(calendar, &year, &month, &day);
 17     month++;    //  月は 0-11 の値で取得されるので +1
 18 
 19     snprintf(ymd, 100, "%d%d%d日", year, month, day);
 20 
 21     gtk_entry_set_text(text, ymd);
 22 }

gtk_calendar_get_date() を使って、カレンダー上で選択された年月日を取得することができる。
ここで注意したいのは、GtkCalendar は月を 0-11 の範囲で扱うということ。したがって上記のように月を取得すると、実際の月より1少ない値が返ってくる(10月なら 9)。逆にカレンダーの表示月を指定するような場面では、1少ない値を月に指定する必要がある。今回のサンプルでは、年月日を取得したあと、月の値をプラス1している。

 57     g_signal_emit_by_name(calendar, "day-selected", text);

アプリケーション起動直後、カレンダー上では今日の日付が選択された状態になっている。しかしテキストエリアには日付が表示されていない。前述の disp_day 関数が起動後一度も実行されていないからだ。
これではカッコ悪いので、g_signal_emit_by_name() を使って "day-selected" シグナルを意図的に発生させ、今日の日付がテキストエリアに表示された状態にしておく。


単純な例で実用性に乏しいかもしれないが、コールバック関数を、例えば指定された日付の予定を表示するような処理に置き換えれば、スケジュール管理アプリみたいになって良いかも。