初心者の初心者による初心者のためのC言語講座

小さなデジタル時計を作ってみよう!
(作成編)




どんなソフトを作るの?

今まで作成して来た、コンソール上のソフトは、そこそこ使えるもの でしたが、視覚的な楽しみがありませんでした。そこで、グラフィカルな ソフトウェアの作成も行って行きましょう。

小さなデジタル時計「Y_clock」

上の図のような、デジタル時計を作ってみましょう。まあ、味もそっけもない 時計ですが、デスクトップの隅に置くぐらいでは、邪魔にならないでしょう。

時計などのいわゆる「デスクトップアクセサリ」と呼ばれるものは、世の中に 結構たくさんありますが、やはり 「自作する楽しみ」 は味わいたいものです。世の中にある時計は、いろいろと高機能なもの ですが、この時計は本当に時間を表示するだけです。

上の図のようなグラフィカルなソフトウェアの作成には、ちょっとした ツールが必要です。今回はGTK+という ツールを使って作成することにします。



GTK+って何?

GTK+とは、 Gimpという、お絵書きソフトを作るために 設計された、GUI (Graphical User Interface を実現するためのツールキットです。まあ、

ボタンなどのグラフィカルなソフトを作るための道具

とでも理解して頂いていれば良いでしょう。

GTK+を使って、グラフィカルなソフトの作成には、当然GTK+がシステムに インストールされている必要があります。 gtk-1.2.*など、いろいろなツールが 必要ですが、今回は簡単にGimpを インストールしてしまいましょう。そうすれば、必要なツールが 全てインストールされます。

/stand/sysinstall を使って、 Gimpをインストールしてください。



さっそく作る

さっそく、作って行きましょう。ソースは以下の通りです。 (ちょっと長いですが…)

1:    #include    < gtk/gtk.h>
2:    #include    < stdio.h>
3:    #include    < time.h>
4:    
5:    typedef    struct    {
6:            GtkWidget    *year_entry;
7:            GtkWidget    *month_entry;
8:            GtkWidget    *day_entry;
9:            GtkWidget    *week_entry;
10:            GtkWidget    *am_pm_entry;
11:            GtkWidget    *hour_entry;
12:            GtkWidget    *min_entry;
13:            GtkWidget    *sec_entry;
14:    }    Y_Clock;
15:    
16:    void    time_display(    Y_Clock    *y_clock    );
17:    
18:    int    main(    int    argc,    char    *argv[]    )
19:    {
20:            Y_Clock    *y_clock;
21:            GtkWidget    *window;
22:            GtkWidget    *hbox;
23:            GtkWidget    *colon;
24:            gint    i    =    0;
25:    
26:            y_clock=(Y_Clock    *)g_malloc(sizeof(Y_Clock));
27:    
28:            gtk_set_locale();
29:            gtk_init(&argc,&argv);
30:    
31:            window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
32:            gtk_signal_connect(GTK_OBJECT(window)," destroy" ,
33:                    GTK_SIGNAL_FUNC(gtk_main_quit),NULL);
34:            gtk_window_set_title(    GTK_WINDOW(window),    " Y_clock"     );
35:    
36:            hbox=gtk_hbox_new(    FALSE,    0    );
37:            gtk_container_add(    GTK_CONTAINER(window),    hbox);
38:            gtk_widget_show(    hbox    );
39:    
40:            y_clock-> year_entry=gtk_entry_new();
41:            gtk_widget_set_usize    (    GTK_WIDGET(y_clock-> year_entry),    84,    -1);
42:            gtk_entry_set_editable    (    GTK_ENTRY(y_clock-> year_entry),    FALSE);
43:            gtk_box_pack_start    (    GTK_BOX(hbox),
44:                    y_clock-> year_entry,    FALSE,    FALSE,    0);
45:            gtk_widget_show    (    y_clock-> year_entry    );
46:    
47:            colon=gtk_label_new(" 年" );
48:            gtk_box_pack_start(GTK_BOX(hbox),colon,FALSE,FALSE,0);
49:            gtk_widget_show(    colon    );
50:    
51:            y_clock-> month_entry=gtk_entry_new();
52:            gtk_widget_set_usize(    GTK_WIDGET(y_clock-> month_entry),    42,    -1);
53:            gtk_entry_set_editable(    GTK_ENTRY(y_clock-> month_entry),    FALSE);
54:            gtk_box_pack_start(GTK_BOX(hbox),
55:                    y_clock-> month_entry,    FALSE,    FALSE,    0);
56:            gtk_widget_show(    y_clock-> month_entry    );
57:    
58:            colon=gtk_label_new(" 月" );
59:            gtk_box_pack_start(    GTK_BOX(hbox),    colon,    FALSE,    FALSE,    0);
60:            gtk_widget_show(    colon    );
61:    
62:            y_clock-> day_entry=gtk_entry_new();
63:            gtk_widget_set_usize(    GTK_WIDGET(y_clock-> day_entry),    42,    -1    );
64:            gtk_entry_set_editable(    GTK_ENTRY(y_clock-> day_entry),    FALSE    );
65:            gtk_box_pack_start(    GTK_BOX(hbox),   
66:                    y_clock-> day_entry,    FALSE,    FALSE,    0);
67:            gtk_widget_show(    y_clock-> day_entry    );
68:    
69:            colon=gtk_label_new(" 日" );
70:            gtk_box_pack_start(    GTK_BOX(hbox),    colon,    FALSE,    FALSE,    0);
71:            gtk_widget_show(    colon    );
72:    
73:            y_clock-> week_entry=gtk_entry_new();
74:            gtk_widget_set_usize(    GTK_WIDGET    (y_clock-> week_entry),    63,    -1    );
75:            gtk_entry_set_editable(    GTK_ENTRY    (y_clock-> week_entry),    FALSE);
76:            gtk_box_pack_start(    GTK_BOX    (hbox),   
77:                    y_clock-> week_entry,    FALSE,    FALSE,    0    );
78:            gtk_widget_show(    y_clock-> week_entry    );
79:    
80:            colon=gtk_label_new("             " );
81:            gtk_box_pack_start(    GTK_BOX(hbox),    colon,    FALSE,    FALSE,    0);
82:            gtk_widget_show(    colon    );
83:    
84:            y_clock-> am_pm_entry=gtk_entry_new();
85:            gtk_widget_set_usize(    GTK_WIDGET    (y_clock-> am_pm_entry),    42,    -1);
86:            gtk_entry_set_editable(    GTK_ENTRY    (y_clock-> am_pm_entry),    FALSE    );
87:            gtk_box_pack_start(    GTK_BOX(hbox),   
88:                    y_clock-> am_pm_entry,    FALSE,    FALSE,    0);
89:            gtk_widget_show(    y_clock-> am_pm_entry    );
90:    
91:            colon=gtk_label_new("             " );
92:            gtk_box_pack_start(    GTK_BOX(hbox),    colon,    FALSE,    FALSE,    0);
93:            gtk_widget_show(    colon    );
94:    
95:            y_clock-> hour_entry=gtk_entry_new();
96:            gtk_widget_set_usize    (GTK_WIDGET    (y_clock-> hour_entry),    42,    -1);
97:            gtk_entry_set_editable    (GTK_ENTRY    (y_clock-> hour_entry),    FALSE);
98:            gtk_box_pack_start    (GTK_BOX    (hbox),
99:                    y_clock-> hour_entry,    FALSE,    FALSE,    0);
100:            gtk_widget_show    (y_clock-> hour_entry);
101:    
102:            colon=gtk_label_new(" 時" );
103:            gtk_box_pack_start(    GTK_BOX(hbox),    colon,    FALSE,    FALSE,    0);
104:            gtk_widget_show(    colon    );
105:    
106:            y_clock-> min_entry=gtk_entry_new();
107:            gtk_widget_set_usize    (GTK_WIDGET    (y_clock-> min_entry),    42,    -1);
108:            gtk_entry_set_editable    (GTK_ENTRY    (y_clock-> min_entry),    FALSE);
109:            gtk_box_pack_start    (GTK_BOX    (hbox),
110:                    y_clock-> min_entry,    FALSE,    FALSE,    0);
111:            gtk_widget_show    (y_clock-> min_entry);
112:    
113:            colon=gtk_label_new(" 分" );
114:            gtk_box_pack_start(    GTK_BOX(hbox),    colon,    FALSE,    FALSE,    0);
115:            gtk_widget_show(    colon    );
116:    
117:            y_clock-> sec_entry=gtk_entry_new();
118:            gtk_widget_set_usize    (GTK_WIDGET    (y_clock-> sec_entry),    42,    -1);
119:            gtk_entry_set_editable    (GTK_ENTRY    (y_clock-> sec_entry),    FALSE);
120:            gtk_box_pack_start    (GTK_BOX    (hbox),
121:                    y_clock-> sec_entry,    FALSE,    FALSE,    0);
122:            gtk_widget_show    (y_clock-> sec_entry);
123:    
124:            colon=gtk_label_new(" 秒" );
125:            gtk_box_pack_start(    GTK_BOX(hbox),    colon,    FALSE,    FALSE,    0);
126:            gtk_widget_show(    colon    );
127:    
128:            gtk_widget_show(    window    );
129:    
130:            i    =    gtk_timeout_add    (1000,    (GtkFunction)time_display,    y_clock);
131:    
132:            gtk_main();
133:    
134:            gtk_timeout_remove(i);
135:    
136:            return    (0);
137:    }
138:    
139:    void    time_display(    Y_Clock    *y_clock    )
140:    {
141:            char    tmp[20];
142:            time_t    ltime;
143:            struct    tm    *today;
144:            int    i=0;
145:    
146:            ltime    =    time(    NULL    );
147:            today    =    localtime(    <ime    );
148:    
149:            sprintf(    tmp,    "                         %04d" ,    today-> tm_year+1900);
150:            gtk_entry_set_text    (GTK_ENTRY    (y_clock-> year_entry),    tmp);
151:            sprintf(tmp,    "         %02d" ,    today-> tm_mon+1);
152:            gtk_entry_set_text    (GTK_ENTRY    (y_clock-> month_entry),    tmp);
153:            sprintf(tmp,    "         %02d" ,    today-> tm_mday);
154:            gtk_entry_set_text    (GTK_ENTRY    (y_clock-> day_entry),    tmp);
155:    
156:            i    =    today-> tm_wday;
157:            switch    (    i    ){
158:                    case    0:
159:                            sprintf(tmp,    "         日曜日" );
160:                            gtk_entry_set_text    (GTK_ENTRY    (y_clock-> week_entry),    tmp);
161:                            break;
162:                   
163:                    case    1:
164:                            sprintf(tmp,    "         月曜日" );
165:                            gtk_entry_set_text    (GTK_ENTRY    (y_clock-> week_entry),    tmp);
166:                            break;
167:    
168:                    case    2:
169:                            sprintf(tmp,    "         火曜日" );
170:                            gtk_entry_set_text    (GTK_ENTRY    (y_clock-> week_entry),    tmp);
171:                            break;
172:    
173:                    case    3:
174:                            sprintf(tmp,    "         水曜日" );
175:                            gtk_entry_set_text    (GTK_ENTRY    (y_clock-> week_entry),    tmp);
176:                            break;
177:    
178:                    case    4:
179:                            sprintf(tmp,    "         木曜日" );
180:                            gtk_entry_set_text    (GTK_ENTRY    (y_clock-> week_entry),    tmp);
181:                            break;
182:    
183:                    case    5:
184:                            sprintf(tmp,    "         金曜日" );
185:                            gtk_entry_set_text    (GTK_ENTRY    (y_clock-> week_entry),    tmp);
186:                            break;
187:    
188:                    case    6:
189:                            sprintf(tmp,    "         土曜日" );
190:                            gtk_entry_set_text    (GTK_ENTRY    (y_clock-> week_entry),    tmp);
191:                            break;
192:    
193:                    default:
194:                            break;
195:            }
196:    
197:            i    =    today-> tm_hour;
198:            if(    i    >     12    ){
199:                    i    =    i    -    12;
200:                    sprintf(tmp,    "         PM" );
201:                    gtk_entry_set_text    (GTK_ENTRY    (y_clock-> am_pm_entry),    tmp);
202:            }else{
203:                    sprintf(tmp,    "         AM" );
204:                    gtk_entry_set_text    (GTK_ENTRY    (y_clock-> am_pm_entry),    tmp);
205:            }
206:    
207:            sprintf(tmp,    "         %02d" ,    i);
208:            gtk_entry_set_text    (GTK_ENTRY    (y_clock-> hour_entry),    tmp);
209:            sprintf(tmp,    "         %02d" ,    today-> tm_min);
210:            gtk_entry_set_text    (GTK_ENTRY    (y_clock-> min_entry),    tmp);
211:            sprintf(tmp,    "         %02d" ,    today-> tm_sec);
212:            gtk_entry_set_text    (GTK_ENTRY    (y_clock-> sec_entry),    tmp);
213:    
214:            return;
215:    }
216:    
y_clock.c

これを、y_clock.cとして、保存します。



コンパイル

さて、ソースを書いたら早速コンパイルなのですが、コンパイルには 今までのコンソール上のプログラムとちがって、すこし違った形を 取らなければなりません。
とりあえず、以下のようにコマンドを打ってください

> which gtk-config
/usr/bin/gtk-config
>

このように表示されたでしょうか?   Linux Userの方は おそらくこのように帰ってきたのではないでしょうか?
もし、上のように帰って来なかった(おそらくFreeBSD Userの方)は 以下のようにコマンドを打ってください

> which gtk12-config
/usr/X11R6/bin/gtk12-config
>

このように帰ってきたでしょうか?   もし、gtk-configで 「コマンドが見つからない」と帰って来て、gtk12-configではコマンドが 見つかった方は、以下のように、 gtk12-config にエイリアスを作ってください。

> su
Password         <- rootのパスワードを入力
# cd   /usr/X11R6/bin
# ln -s gtk12-config gtk-config
#

これで gtk12-config に gtk-config のシンボリックリンクを張ることが できました。

ソースのコンパイルは

gcc -o 実行ファイル名   ソースファイル名   `gtk-config   --cflags`   `gtk-config   --libs`

と、このようにコンパイルします。「`」マークに気をつけてください。 日本語キーボードでは「@」の位置にあるマークです。「7」の所にある クォーテーションではないのでお間違いのないように。

今回の y_clock.c であれば、

gcc -o   y_clock   y_clock.c   `gtk-config   --cflags`   `gtk-config   --libs`

と、このようにコンパイルしてください。実行ファイル名は y_clockです。



→解説編(1)に続く→



質問等については ここ にメールを送ってください


CONTENTSに戻る