分123今回は,ステートマシーンフレームワークの最後です。マウスやキーイベント遷移がどのようなものか,イベント遷移の独自拡張,そして履歴状態や並列状態,遷移とアニメーション効果について説明します。前回取り上げたシグナル遷移はステートマシンフレームワークのリファレンスで,コード例を示して説明していますが,マウスイベント遷移とキーイベント遷移についてはシグナル遷移のような説明がありません。そこで,簡単なコードで,まずマウス遷移を説明しましょう。マウスイベント遷移の説明のためにEventWidgetウィジェットを作りました。プロパティがfalse)赤色で描画するようにします。ボタンが押されている間はPressedと表示されるように,ステートマシンフレームワークで制御をするようにしています。動作は図1のようになります。#endifEventWidgetのヘッダです。今までも見て来たように,ステートマシーンフレームワークでは,ある状態になった時にプロパティを変更する仕組みを持っています。そこで,textプロパティでテキストをアクセスできるようにしておき,状態が変わった時にQState::assignProperty()でテキストを変えられるようにしておきます。呼び出して,背景色で塗り潰されるようにします。有効化と無効化の各状態でのテキストの色は,パレットのQPalette::NormalとQPalette::Disabledの各カラーグループごとに,QPalette::WindowTextロールで指定します。しておくとテキスト描画時に,QPainter::drawText()が用いる色が有効化/無効化に合わせてパレットから取り出されて使われます。通常状態とボタンが押されている状態を用意しています。本連載の第4回「ステートマシーンフレームワーク」の図1「ステートマシンフレームワークのクラス」で示したように,QEventTransitionクラスは,マウスとキーイベントのベースクラスになっています。その基本機能は,イベントタイプに対して反応する遷移となっていて,コンストラクタで指定した状態の時に,指定したタイプのイベントが発生すると遷移が起きます。pressTransitionは,このウィジェットidleState状態にある時にイベントタイプがQEvent::MouseButtonPressのイベントが発生すると,pressedState状態への遷移が起きます。);QEventTransitionの代わりにそのサブクラスのQMouseEventTransitionを使うと上記のように書けて,どのボタンで遷移するかも指定できます。この場合には,左ボタンでのみ遷移が起きるようになります。Xでは,左ボタンを押したまま右ボタンをクリックしてから左ボタンを離しても左ボタンのリリースイベントが出ないためidleStateに戻らず,意図した動きになりません。ステートマシンの動かし方は今まで通りです。textプロパティのゲッターとセッターで,テキストが変更されたならば,update()で再描画イベントがスケジュールされるようにし,updateGeometry()でレイアウトマネージャにレイアウトの変更を知らせて,テキストの大きさの変更に追従させます。テキストが表示される最小限の大きさをsizeHint()で返すようにして,レイアウトマネージャがちょうどよい大きさでこのウィジェットを配置するようにします。}前述したようにパレットで背景色と状態に合わせた色を設定しているので,drawText()でテキストを描画するだけで,ウィジェットの背景が灰色になり,テキストにも状態に合った色が付きます。"main.moc"有効化と無効化の両状態のEventWidgetを表示して動作を確認するコードです。図2のように無効化されていてもマウスイベント遷移が起きます。無効状態でもマウスイベント遷移をしてしまうこれはウィジェットのイベントへの振舞いを考えると,直感に反した動作でしょう。QWidgetは無効化されていれば,QWidget::event()でQEvent::MouseButtonPressやQEvent::MouseButtonReleaseに対して対応するイベントハンドラーを呼び出しません。QWidgetのリファレンスにもそのように書かれています。以下のようにQMouseEventTransitionは,QObjectを受け付けるようになっています。)QObjectである必要はであるでしょう。マウスイベントはウィジェットと密接に関連しているので,enabledプロパティに従うのが直感にも合った動きです。対象がウィジェットならば,QMouseEventTransitionにenabledプロパティに従ってイベントを扱うようなオプションがあってもよさそうに思えます。