
C言語GUI入門|GUI電卓の仕様を決める
第6章では、2つの数値を入力して四則演算を実行できるGUI電卓を作成します。
GUIアプリケーションを作るときは、すぐにプログラムを書き始めるのではなく、最初に必要な機能や画面の構成を整理しておくことが大切です。仕様を先に決めておけば、どのウィジェットが必要なのか、どのようなコールバック関数を作ればよいのかが分かりやすくなります。
この記事では、次の内容を決めます。
- GUI電卓でできること
- 入力できる値
- 画面に配置するウィジェット
- 四則演算の動作
- 計算結果の表示方法
- 入力エラーが発生したときの動作
- クリアボタンを押したときの動作
- 第6章で完成させる画面のイメージ
この節では、まだcalculator.cのプログラムは作成しません。次の6.2からファイルを準備し、少しずつ機能を追加していきます。
GUI電卓でできることを決めよう
今回作成するGUI電卓では、2つの入力欄に数値を入力し、演算ボタンをクリックして計算します。
実装する機能は次のとおりです。
| 機能 | 内容 |
|---|---|
| 数値の入力 | 2つのGtkEntryに計算したい数値を入力する |
| 足し算 | 1つ目の値と2つ目の値を加算する |
| 引き算 | 1つ目の値から2つ目の値を減算する |
| 掛け算 | 1つ目の値と2つ目の値を乗算する |
| 割り算 | 1つ目の値を2つ目の値で除算する |
| 結果の表示 | 計算結果をGtkLabelに表示する |
| 入力の確認 | 空欄や数値以外の入力を確認する |
| ゼロ除算の確認 | 0で割ろうとした場合は計算しない |
| 入力内容のクリア | 入力値と計算結果を初期状態へ戻す |
今回の電卓は、複雑な関数を扱う関数電卓ではありません。四則演算の基本を通して、GtkEntryから入力を取得する方法、文字列を数値へ変換する方法、ボタンのクリックを処理する方法などを学ぶことが目的です。
図1:GUI電卓の基本機能

この図から分かること
今回のGUI電卓は、2つの入力欄、4つの演算ボタン、計算結果を表示するラベル、クリアボタンで構成されます。
利用者は、次の順番で電卓を操作します。
- 1つ目の数値を入力する
- 2つ目の数値を入力する
- 実行したい演算ボタンをクリックする
- 計算結果を確認する
- 必要に応じてクリアボタンをクリックする
入力できる値を決める
GtkEntryへ入力した内容は、数値としてではなく文字列として取得されます。
たとえば、画面に12.5と入力しても、プログラムが最初に受け取るのは数値の12.5ではなく、文字が並んだ12.5です。そのため、計算する前に文字列を数値へ変換しなければなりません。
今回の電卓では、次のような値を入力できる仕様にします。
| 入力例 | 判定 | 説明 |
|---|---|---|
| 25 | 有効 | 正の整数 |
| -8 | 有効 | 負の整数 |
| 3.14 | 有効 | 小数 |
| -0.75 | 有効 | 負の小数 |
| +10 | 有効 | プラス記号が付いた数値 |
| 1e3 | 有効 | strtodで変換できる指数表記 |
| 空欄 | 無効 | 数値が入力されていない |
| 空白だけ | 無効 | 数値として扱わない |
| ABC | 無効 | 数値へ変換できない |
| 12ABC | 無効 | 数値以外の文字が含まれている |
| nan | 無効 | 通常の有限な数値として扱わない |
| inf | 無効 | 通常の有限な数値として扱わない |
整数だけでなく小数も計算できるようにするため、入力値はdouble型へ変換します。
文字列から数値への変換にはstrtodを使用します。strtodは変換後の値だけでなく、文字列のどこまでを数値として変換できたかも確認できます。そのため、12ABCのような入力を正しくエラーとして扱えます。
四則演算の動作を決める
2つの入力値を、それぞれvalue1とvalue2として考えてみましょう。
各ボタンをクリックしたときの計算方法は次のようになります。
| ボタン | 演算 | 計算内容 |
|---|---|---|
| 足し算 | 加算 | value1 + value2 |
| 引き算 | 減算 | value1 - value2 |
| 掛け算 | 乗算 | value1 × value2 |
| 割り算 | 除算 | value1 ÷ value2 |
引き算と割り算では、値の順番が重要です。
たとえば、1つ目の入力欄に10、2つ目の入力欄に2を入力した場合、計算結果は次のようになります。
| 操作 | 計算 | 表示結果 |
|---|---|---|
| 足し算 | 10 + 2 | 計算結果:12 |
| 引き算 | 10 - 2 | 計算結果:8 |
| 掛け算 | 10 × 2 | 計算結果:20 |
| 割り算 | 10 ÷ 2 | 計算結果:5 |
2つ目の値から1つ目の値を引いたり、2つ目の値を1つ目の値で割ったりする仕様ではない点に注意しましょう。
必要なウィジェットを整理しよう
今回のGUI電卓では、画面の部品として複数のウィジェットを使用します。
| ウィジェット | 個数 | 役割 |
|---|---|---|
| GtkApplicationWindow | 1 | GUI電卓全体を表示するウィンドウ |
| GtkGrid | 1 | ラベル、入力欄、ボタンを表のように配置する |
| GtkLabel | 3 | 入力欄の説明と計算結果を表示する |
| GtkEntry | 2 | 2つの数値を入力する |
| GtkButton | 5 | 四則演算とクリア操作を実行する |
GtkLabelは、次の3か所で使用します。
- 1つ目の数値を案内するラベル
- 2つ目の数値を案内するラベル
- 計算結果やエラーメッセージを表示するラベル
GtkButtonは、次の5個を配置します。
- 足し算ボタン
- 引き算ボタン
- 掛け算ボタン
- 割り算ボタン
- クリアボタン
画面のレイアウトを決める
ウィジェットはGtkGridを使って表のように配置します。
画面の上から順番に、次のような構成にします。
| 行 | 左側 | 右側 |
|---|---|---|
| 1行目 | 1つ目の数値を示すラベル | 1つ目のGtkEntry |
| 2行目 | 2つ目の数値を示すラベル | 2つ目のGtkEntry |
| 3行目 | 足し算ボタン、引き算ボタン | 掛け算ボタン、割り算ボタン |
| 4行目 | 計算結果を表示するGtkLabel | 複数列を使って配置 |
| 5行目 | クリアボタン | 複数列を使って配置 |
演算ボタンは4個あるため、実際にはGtkGrid上で横方向に並べます。結果ラベルとクリアボタンは、必要に応じて複数の列にまたがるように配置します。
図2:GUI電卓を構成するウィジェット

この図から分かること
GtkApplicationWindowの中には、レイアウトを管理するGtkGridを1つ配置します。さらに、GtkGridの子ウィジェットとして入力欄、演算ボタン、結果ラベルなどを配置します。
GtkEntryやGtkButtonを直接ばらばらに管理するのではなく、GtkGridへまとめて配置することで、画面を行と列に沿って整えられます。
このウィジェット階層は、6.2で改めて整理し、6.3で実際のプログラムとして作成します。
計算結果の表示方法を決める
計算結果は、画面内のGtkLabelに表示します。
アプリケーションを起動した直後は、次のように表示します。
計算結果:正常に計算できた場合は、同じラベルを次のように更新します。
計算結果:12.5計算するたびに新しいラベルを作るのではなく、最初に作成した結果表示用のGtkLabelの文字列を変更します。
結果は、整数と小数の両方を自然に表示できる形式にします。たとえば、計算結果が5の場合は5、3.5の場合は3.5と表示します。必要以上に0が並ばないよう、完成版では表示形式も調整します。
入力エラーが発生したときの動作を決める
GUIアプリケーションでは、利用者が必ず正しい値を入力するとは限りません。入力に問題がある場合は計算を行わず、結果表示用のGtkLabelにエラーメッセージを表示します。
入力欄が空の場合
1つ目の入力欄が空の場合は、次のように表示します。
1つ目の値を入力してください。2つ目の入力欄が空の場合は、次のように表示します。
2つ目の値を入力してください。空白文字しか入力されていない場合も、空欄として扱います。
数値以外が入力された場合
数値へ変換できない文字が入力されている場合は、どちらの入力に問題があるのか分かるメッセージを表示します。
1つ目の値を数値で入力してください。または、次のように表示します。
2つ目の値を数値で入力してください。ABCだけでなく、12ABCのように数値の後ろへ文字が続いている場合もエラーにします。
0で割ろうとした場合
割り算では、2つ目の値が0の場合に計算できません。
この場合は、計算結果の代わりに次のメッセージを表示します。
0では割り算できません。0.0や-0.0も0として扱います。
エラーが発生した入力欄へフォーカスを移す
入力エラーが見つかった場合は、問題のあるGtkEntryへフォーカスを移します。利用者は、そのまま値を入力し直せます。
たとえば、2つ目の入力欄が空だった場合は、2つ目のGtkEntryへフォーカスを移します。
演算ボタンをクリックしたときの流れ
演算ボタンにはclickedシグナルを接続します。利用者がボタンをクリックすると、計算を担当するコールバック関数が呼び出されます。
コールバック関数では、次の順番で処理します。
- 2つのGtkEntryから文字列を取得する
- 入力欄が空でないか確認する
- 文字列をdouble型の数値へ変換する
- 数値へ正しく変換できたか確認する
- 割り算の場合は2つ目の値が0でないか確認する
- 選択された四則演算を実行する
- 計算結果を文字列に変換する
- 結果表示用のGtkLabelを更新する
途中で入力エラーが見つかった場合は、それ以降の計算を行いません。計算結果の代わりにエラーメッセージを表示します。
図3:演算ボタンをクリックしたときの処理

この図から分かること
演算ボタンをクリックしても、すぐに四則演算を実行するわけではありません。最初に文字列を取得し、空欄や数値以外の入力がないことを確認する必要があります。
すべての確認を通過した場合だけ計算を実行し、結果をGtkLabelへ表示します。入力に問題がある場合は、処理を途中で止めてエラーメッセージを表示します。
クリアボタンの動作を決める
クリアボタンをクリックしたときは、GUI電卓を起動直後の状態へ戻します。
実行する処理は次のとおりです。
- 1つ目のGtkEntryを空にする
- 2つ目のGtkEntryを空にする
- 結果ラベルを計算結果:へ戻す
- 1つ目のGtkEntryへフォーカスを移す
クリア後の画面は、次の状態になります。
| 項目 | クリア後の状態 |
|---|---|
| 1つ目の入力欄 | 空欄 |
| 2つ目の入力欄 | 空欄 |
| 結果ラベル | 計算結果: |
| キーボードフォーカス | 1つ目の入力欄 |
エラーメッセージが表示されている場合も、クリアボタンを押すと計算結果:へ戻します。
操作結果の例を確認しよう
完成後のGUI電卓では、次のような操作ができるようにします。
| 1つ目の入力 | 2つ目の入力 | 操作 | 表示内容 |
|---|---|---|---|
| 15 | 7 | 足し算 | 計算結果:22 |
| 15 | 7 | 引き算 | 計算結果:8 |
| 15 | 7 | 掛け算 | 計算結果:105 |
| 15 | 3 | 割り算 | 計算結果:5 |
| 5 | 2 | 割り算 | 計算結果:2.5 |
| -5 | 3 | 足し算 | 計算結果:-2 |
| 空欄 | 3 | 足し算 | 1つ目の値を入力してください。 |
| ABC | 3 | 足し算 | 1つ目の値を数値で入力してください。 |
| 10 | 0 | 割り算 | 0では割り算できません。 |
今回は実装しない機能
作成する機能の範囲を明確にするため、今回は実装しない機能も決めておきましょう。
| 実装しない機能 | 内容 |
|---|---|
| 数字入力ボタン | 0から9までのボタンは配置しない |
| 計算履歴 | 過去の計算結果は保存しない |
| 連続計算 | 前回の結果を自動的に次の計算へ利用しない |
| 関数計算 | 平方根、べき乗、三角関数などは扱わない |
| メモリー機能 | M+、M-、MRなどは実装しない |
| キーボードショートカット | 演算は画面上のボタンで実行する |
機能を四則演算に絞ることで、GtkEntry、GtkButton、GtkLabel、GtkGrid、シグナル、コールバック関数といったGTK 4の基本を一つずつ確認できます。
第6章でGUI電卓を完成させる流れ
GUI電卓は、6.1から6.10までを通して段階的に作成します。
| 節 | 作業内容 |
|---|---|
| 6.1 | GUI電卓の機能と動作を決める |
| 6.2 | chap06とcalculator.cを準備し、ウィジェットの階層を設計する |
| 6.3 | GtkEntry、GtkButton、GtkLabel、GtkGridで画面を作る |
| 6.4 | GtkEntryから入力文字列を取得する |
| 6.5 | strtodで文字列を数値へ変換する |
| 6.6 | 足し算、引き算、掛け算、割り算を実装する |
| 6.7 | 空欄、数値以外、0による割り算に対応する |
| 6.8 | 入力内容と結果を初期状態へ戻す機能を作る |
| 6.9 | GTK CSSで文字サイズや余白を整える |
| 6.10 | プログラム全体を完成させ、コンパイルと動作確認を行う |
次の6.2ではC:\cgui\chap06を準備し、calculator.cを作成します。2章ですでにchap06を作成している場合は、ディレクトリの作成を省略し、そのままcalculator.cの準備へ進めます。








