[ 前へ | 目次 | 次へ ]
Japanese English

イベント処理

ここでは、ユーザーがGUIコンポーネントを操作した際に処理を行う、「イベント処理」について解説します。

スポンサーリンク


イベント駆動プログラミング

これまでは、プログラムを実行すると、あらかじめ決まりきった処理の流れに基づいて、処理が行われてきました。

一方、GUIを用いたプログラムでは、ユーザーがボタンをクリックしたり、マウスを動かしたりした時 に、それぞれに対応した処理を行う必要があります。 「いつ処理されるか」は決められないため、「何かが起こった時に処理する」という形に、処理の流れの考え方を変える必要があるわけです。

このような処理を扱うための仕組みの一つが、「イベント駆動プログラミング」です。VCSSLのGUIの処理は、典型的なイベント駆動プログラミングの仕組みを採用しています。

イベントとは

イベントとは、「何かが起こった時に処理する」における、「起こった何か」を指す用語です。 そして、その「何かが起こった」という事を、「イベントが発生した」と言います。

例えば、「ユーザーがボタンをクリックした」とか、「マウスが操作された」といった事がイベントです。

イベントハンドラ関数

さて、イベントが発生すると、それに対応する関数がシステム側から呼ばれます。 このような関数の事を一般に「イベントハンドラ関数」と呼びます。

イベントハンドラ関数の模式図。
イベントハンドラの概念図
「ボタンがクリックされる」などのイベントが発生すると、イベントハンドラ関数が実行される。

イベントハンドラ関数の内容はあらかじめ用意されているのではなく、プログラムの書き手が自由な内容を記述します。

特定の名前と引数の関数を宣言するだけでOK、登録不要

VCSSLでは、 処理したいイベントの種類に応じて特定の関数名と引数を持たせると、 それが自動的にイベントハンドラ関数と見なされ、イベント発生時に呼び出されます。 特別な登録処理などを行う必要はありません。

イベントハンドラ関数の仕様に共通する特徴

VCSSLのイベントハンドラ関数は、以下のように共通した特徴を持っています:

  • 関数の中身には、イベントが発生した際に行わせたい処理を記述します。
  • 呼び出し時の引数には、イベントに関する情報が送られてきます。引数の数や型は、イベントハンドラによって異なります。
  • 戻り値は基本的に、何も値を返さない「void」型です。

ここからは、実際に様々な種類のイベントと、イベントハンドラ関数の仕様を見ていきましょう。

ウィンドウイベント処理

ウィンドウに関するイベントを処理するには、以下のイベントハンドラ関数を使用します。

イベントハンドラ関数 引数 イベント
onWindowOpen int id ウィンドウが起動した際に呼び出されます。
onWindowClose int id ウィンドウが閉じた際に呼び出されます。
onWindowMove int id,
int x,
int y
ウィンドウが動いた際に呼び出されます。
onWindowResize int id,
int width,
int height
ウィンドウサイズが変わった際に呼び出されます。
onWindowShow int id ウィンドウが表示された際に呼び出されます。
onWindowHide int id ウィンドウが非表示になった際に呼び出されます。

引数は以下の通りです:

  • id: イベントが発生したウィンドウのGUIコンポーネントIDが渡されます。
  • width, height: それぞれウィンドウの幅、高さが渡されます。

ここで特に重要なのがonWindowClose関数です。 このイベントハンドラ関数内で exit() 関数をコールするようにすると、 一般的なソフトウェアのような「 ウィンドウを閉じると処理を終了する 」という機能を実現できます。

これまで、VCSSLプログラムを終了させるには、 VCSSLコンソールを手動で閉じるしかありませんでした。 しかし、ウィンドウを閉じればプログラムが自動終了するようにしておけば、 VCSSLコンソールは不要なので、hide() 命令で隠してしまっても問題ありません。

ボタンイベント処理

ボタンに関するイベントを処理するには、以下のイベントハンドラ関数を使用します。

イベントハンドラ関数 引数 イベント
onButtonClick int id,
string text
ボタンがクリックされた際に呼び出されます。

引数は以下の通りです:

  • id: イベントが発生したボタンのGUIコンポーネントIDが渡されます。
  • text: 押されたボタンの表示文字列が渡されます。

セレクトフィールドイベント処理

セレクトフィールドに関するイベントを処理するには、以下のイベントハンドラ関数を使用します。

イベントハンドラ関数 引数 イベント
onSelectFieldClick int id,
string text
セレクトフィールドがクリックされ、項目が選択された際に呼び出されます。

引数のidには、イベントが発生したセレクトフィールドのGUIコンポーネントIDが渡されます。 また、引数のtextには、選択された項目名が渡されます。

チェックボックスイベント処理

チェックボックスに関するイベントを処理するには、以下のイベントハンドラ関数を使用します。

イベントハンドラ関数 引数 イベント
onCheckBoxClick int id,
bool state
チェックボックスがクリックされた際に呼び出されます。

引数のidには、イベントが発生したチェックボックスのGUIコンポーネントIDが渡されます。 また、引数のstateには、チェックボックスのON/OFF状態が渡されます。

キーイベント処理

GUIコンポーネント上でキーボードのキーを操作した際には、キーイベントが発生します。

注意:

ただし、キーイベントを利用するには、キーイベントがどのGUIコンポーネント上で発生するかという点に関して注意が必要です。

もし、ウィンドウ上に、テキストフィールドなどのキーボード入力を扱うGUIコンポーネントが配置されている場合、キーイベントは優先的にそれらのGUIコンポーネント上で発生します。もしもその横に、グラフィックスラベルなどを配置していて、その上でキーイベントを拾おうとしても、うまく拾えません。

また、ウィンドウ上にボタンなどの特定のキー操作(ENTERなど)に反応するGUIコンポーネントが配置されている場合にも、その特定のキー操作を、他のGUIコンポーネント上でイベントとして拾えない場合もあります。

そのため、テキストラベルやグラフィックスラベルなどの、一般にキー入力がされないGUIコンポーネント上で、キーイベントを利用したい場合は、 ウィンドウ上にテキスト入力系コンポーネントやボタンなどは配置しない事が推奨されます。

キーイベントを処理するには、以下のイベントハンドラ関数を使用します。

イベントハンドラ関数 引数 イベント
onKeyDown int id,
string key
キーが押された際に呼び出されます。
onKeyDown int id,
int keyCode
キーが押された際に呼び出されます。
onKeyUp iint id,
string key
キーが離された際に呼び出されます。
onKeyUp iint id,
int keyCode
キーが離された際に呼び出されます。

引数は以下の通りです:

  • id: イベント発生対象のGUIコンポーネントIDが渡されます。
  • key: キーラベルの文字列が格納されています。記号のキーは、記号の文字列に変換されます。
  • keyCode: 引数keyCodeには、キーを区別するため、GUIライブラリに1対1で定義された値が格納されています。

上記の通り、2つめの引数には、string 型とint型の2通りがあります。 前者は、キーの表面に印字された(キーラベルの)文字列が格納されます。 例えば「A」のキーを押した際は "A" が、「@」のキーを押した際は "@" が格納されます。 それに対して後者は、キーに1対1で割り振られた整数値が格納され、 例えば「@」のキーを押した際はKEY_ATの値が格納されます。

前者と後者にはそれぞれメリットとデメリットがあります。 前者は比較的手軽に扱える上、 連続したキー入力内容をstring変数末尾に追記していくような処理に便利です。 反面、キー判別に key == "@" といったリテラルの文字列比較を多用するのはミスタイプに弱く、 厳格性に欠けるため、大きなプログラムでは好ましくありません。 それに対して後者は、厳格な記述が可能ですが、 小さなプログラムでは記述が面倒になる場合があります。

文字列 キーコード 文字列 キーコード
A〜Z KEY_A〜KEY_Z 0〜9 KEY_0〜KEY_9
F1〜F12 KEY_F1〜KEY_F12 @ KEY_AT
/ KEY_SLASH
ENTER KEY_ENTER + KEY_PLUS
SPACE KEY_SPACE - KEY_MINUS
TAB KEY_TAB , KEY_COMMA
SHIFT KEY_SHIFT . KEY_PERIOD
CONTROL KEY_CONTROL ALT KEY_ALT
; KEY_SEMICOLON [ KEY_LEFT_SQUARE_BRACKET
^ KEY_CIRCUMFLEX ] KEY_RIGHT_SQUARE_BRACKET
UP KEY_UP DOWN KEY_DOWN
LEFT KEY_LEFT RIGHT KEY_RIGHT

マウスウイベント処理

GUIコンポーネント上でマウスを動かしたり、 クリックしたりすると、マウスイベントが発生します。 マウスイベントを処理するには、以下のイベントハンドラ関数を使用します。

マウス操作は行えるアクションが多彩なので、 それに応じてイベントハンドラも様々なものが用意されています。

イベントハンドラ関数 引数 イベント
onMouseOver int id,
int x,
int y
マウスがコンポーネント領域内に入った際に呼び出されます。
onMouseOut int id,
int x,
int y
マウスがコンポーネント領域外に出た際に呼び出されます。
onMouseMove iint id,
int x,
int y
マウスがコンポーネント領域内で動いた際に呼び出されます。
onMouseCkick int id,
int x,
int y,
int button,
int count
マウスのボタンがクリックされた際に呼び出されます。具体的には、環境に設定された短い時間内で、マウスボタンが「 押し離し 」された場合に呼ばれます。
onMouseDown int id,
int x,
int y,
int button
マウスのボタンが押された際に呼び出されます。
onMouseUp int id,
int x,
int y,
int button
マウスのボタンが離された際に呼び出されます。
onMouseDrag int id,
int x,
int y,
int button
マウスのいずれかのボタンがドラッグされた際に呼び出されます。
onMouseScroll int id,
int degree
マウスホイールが操作された際に呼び出されます。

引数は以下の通りです:

  • id: イベント発生対象のGUIコンポーネントIDが渡されます。
  • x, y: コンポーネントの左上を原点とするマウスカーソル座標が格納されます。
  • button: 押されたボタンを区別するため、GUIライブラリに定義された値が格納されます。定数値は、右, 左, 中央ボタンがそれぞれMOUSE_RIGHT, MOUSE_LEFT, MOUSE_MIDDLEという名称です。
  • count: 最後の引数countは、連続して押し離しされた回数が格納されます。つまりシングルクリックなら1、ダブルクリックなら2となります。この値は、GUIライブラリにもそれぞれMOUSE_SINGLE, MOUSE_DOUBLEと定義されており、比較などで用いるとミスタイプを防げます。
  • degree: ホイール回転量(細かい刻み単位)が渡されます。

プログラム例

実際に各種イベントハンドラ関数を使用してみましょう。 以下のように記述し、実行してみてください。


import GUI ;
import Graphics ;


// =============================================
// GUIコンポーネントの配置 ここから
// =============================================

// ( x, y ) = ( 300, 20 ) の位置に幅360×高さ480のウィンドウを生成
int windowID = newWindow( 300, 20, 360, 480, "Hello GUI" ) ;

// ( 10, 10 ) の位置に100×50のボタンを配置
int buttonID = newButton ( 10, 10, 100, 50, "PUSH" ) ;
mountComponent( buttonID, windowID ) ;

// ( 10, 70 ) の位置に100×50サイズのテキストフィールドを配置
int textFieldD = newTextField( 10, 70, 100, 30, "INPUT" ) ;
mountComponent( textFieldD, windowID ) ;

// ( 120, 10 ) の位置に200×200サイズのテキストエリアを配置
int textAreaID = newTextArea( 120, 10, 200, 200, "INPUT" ) ;
mountComponent( textAreaID, windowID ) ;

// ( 10, 110 ) の位置に100×20サイズのセレクトフィールドを配置
string text[ 3 ] ;
text[ 0 ] = "TYPE-A";
text[ 1 ] = "TYPE-B";
text[ 2 ] = "TYPE-C";
int selectFieldID = newSelectField( 10, 110, 100, 20, text ) ;
mountComponent( selectFieldID, windowID ) ;

// ( 10, 140 ) の位置に100×20サイズのチェックボックスを作成
int checkBoxID = newCheckBox( 10, 140, 100, 20, "TURBO", true ) ;
mountComponent( checkBoxID, windowID ) ;

// ( 10, 170 ) の位置に100×20サイズのテキストラベルを配置
int textLabelID = newTextLabel( 10, 170, 100, 20, "Hello GUI ! " ) ;
mountComponent( textLabelID, windowID ) ;

// 「Test.png」という名前のPNG形式画像ファイルを読み込み
int graphicsID = newGraphics( "Test.png" ) ;
// ( 10, 220 )の位置に310×200サイズの画像ラベルを配置
int imageLabelID = newImageLabel( 10, 220, 310, 200, graphicsID ) ;
mountComponent( imageLabelID, windowID ) ;

// =============================================
// GUIコンポーネントの配置 ここまで
// =============================================


// =============================================
// イベントハンドラ ここから
// =============================================

// ウィンドウを閉じた際に呼び出される
void onWindowClose( int id ){
	alert( "プログラムを終了します。" ) ;
	exit( );
}

// ボタンクリック時に呼び出される
void onButtonClick( int id, string text ){
	alert( "ボタン " + text + " がクリックされました。" ) ;
}

// セレクトフィールド選択時に呼び出される
void onSelectFieldClick( int id, string text ){
	alert( text + " が選択されました。" ) ;
}

// チェックボックス選択時に呼び出される
void onCheckBoxClick( int id, bool state ){
	alert( "選択状態が " + state + " になりました。" ) ;
}

// マウスドラッグ時に呼び出される
void onMouseDrag( int id, int x, int y, int button ){
	// ドラッグされたコンポーネントの判別
	if( id == imageLabelID ){
		// マウスボタンの判別
		if( button == MOUSE_RIGHT ){
			println( "右ドラッグ X=" + x + " Y=" + y ) ;
		}else if( button == MOUSE_LEFT ){
			println( "左ドラッグ X=" + x + " Y=" + y ) ;
		}
	}
}

// マウスクリック時に呼び出される
void onMouseClick( int id, int x, int y, int button, int count ){
	// クリックされたコンポーネントの判別
	if( id == imageLabelID ){

		// マウスボタンの判別
		if( button == MOUSE_RIGHT ){
			println( "右クリック X=" + x + " Y=" + y ) ;
		}else if( button == MOUSE_LEFT ){
			println( "左クリック X=" + x + " Y=" + y ) ;
		}

		// ダブルクリックの判別
		if( count == MOUSE_DOUBLE ){
			alert( "ダブルクリックされました。" );
		}

	}
}

// キー入力時に呼び出される(キーラベル文字列取得)
void onKeyDown( int id, string key ){
	println( "キー入力 =" + key ) ;
}

// キー入力時に呼び出される(キーコード取得)
void onKeyDown( int id, int keyCode ){
	if( keyCode == KEY_SPACE ){
		alert( "スペースキーが押されました。" ) ;
	}
}

// =============================================
// イベントハンドラ ここまで
// =============================================
EventSample.vcssl

このプログラムを実行すると、ウィンドウが表示され、その上に様々なGUIコンポーネントが表示されます。 各GUIコンポーネントを操作すると、それに応じた処理が実行されます。

実行結果の図。
実行結果
※この画像は模式図です。実際のGUIデザインは、オペレーティングシステムの種類や、VCSSL処理システムのバージョン、その他環境によって異なります。


スポンサーリンク



Japanese English
この階層の目次
RINEARN からのお知らせ
※ VCSSL は RINEARN が開発しています。

VCSSLのサポートAIが登場! ただし実用品質には ChatGPT 有料アカウント(Plus)での利用推奨
2025-08-19 - プログラミング言語VCSSLについての質問対応や、コーディング作業を手伝ってくれるAIさんが登場しました! 使用までの流れや推奨事項を解説し、実際の回答例や生成コード例などもたくさん紹介します!

各ソフトやVCSSLの英語版ドキュメント整備がほぼ完了
2025-06-30 - RINEARNでは2年前から、AIの補助による英語版ドキュメントの大幅拡充計画を進めてきました。今回、主要ドキュメント&コンテンツの英訳がほぼ完了し、一応の目標水準に達しました。詳細をお知らせします。

VCSSLの最新版をリリース: 外部プログラムとの連携機能を少し強化、他
2025-05-25 - VCSSL 3.4.52をリリースしました。外部プログラム(C言語製の実行ファイル等)との連携機能を少し強化し、文字化け対策やOS判別などを可能にしました。他にも細かい機能追加があります。詳細をお知らせします。

VCSSLの最新版をリリース、Java 24上での非互換な挙動を対処
2025-04-22 - VCSSL 3.4.50をリリースしました。Java 24環境上でのネットワークドライブ関連のファイルパス解決で、従来環境とは異なる挙動が生じていたのを解消しました。詳細をお知らせします。

リニアングラフやVCSSLの最新版をリリース、目盛りの位置や内容を自由に指定可能に!
2024-11-24 - リニアングラフ3D/2Dを更新し、自由な位置に、自由な表記内容の目盛りを描けるようになりました! 併せて、Java言語やVCSSLでの、プログラム制御用APIも拡張しています。詳細をお知らせします。

Exevalator 2.2 をリリース、TypeScript 対応によりWebブラウザ上で動作可能に
2024-10-22 - オープンソースの式計算ライブラリ「Exevalator(エグゼバレータ)」の2.1をリリースしました。新たに TypeScript に対応し、Webブラウザ上での式計算にも使えるようになりました。詳細を解説します。

アシスタントAI作成の舞台裏(その2、作成編)
2024-10-12 - アシスタントAIの作成方法解説の後編です。実際にChatGPTの「GPTs」機能を用いて、アシスタントAIを作成する手順や、独自の知識をもたせたり、精度を出すためのノウハウなどを解説しています。

アシスタントAI作成の舞台裏(その1、基礎知識編)
2024-10-07 - アシスタントAI作成方法解説の前編です。今回はまず、アシスタントAIを作る前に抑えておきたい、基礎知識を延々と解説しています。そもそもLLM型AIとはどんな存在か? RAGとは何か? 等々です。

ソフトの利用をサポートしてくれるアシスタントAIを提供開始!
2024-09-20 - RINEARN製ソフトの使い方の質問応答や、一部作業のお手伝いをしてくれる、アシスタントAIを提供開始しました。ChatGPTアカウントさえあれば、誰でも無料で使用できます。使い方を解説します。

Exevalator 2.1 をリリース、新たに Visual Basic に対応
2024-07-28 - オープンソースの式計算ライブラリ「Exevalator(エグゼバレータ)」の2.1をリリースしました。今回から、新たに Visual Basic(VB.NET)でも使用できるようになりました。詳細を解説します。