この記事で扱っていること
- マウスオーバーでプレビューを表示させる方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
LabVIEWの標準機能として、ヒントラベルというものがあります。
これは、プログラムの実行中に、制御器や表示器などにマウスオーバーする(マウスをそれら制御器や表示器等の対象に重ねる)ことで、それらの使い方などを表示させる機能です。
これはプログラム的に表示させる文字の内容も変えられたり、ユーザーがプログラムを使用するのに親切な設計とするには便利なのですが、文字しか扱えません。
しかし、時には図なんかを表示したい場面があると思います。
例えばメインVI上にあるボタンを押すと別のサブVIが表示されてそのサブVIを実行するようなプログラムで、そういったボタンが複数ある場合、どのボタンを押すとどのような画面が開くかのプレビューを見るような場合です。
ヒントラベルではこのようなことはできないので、プレビューを見るための機能を実装する必要があり、本記事ではその一例を紹介しています。
どんな結果になるか
今回は例として、メインVI上に二つのボタンがあり、それぞれを押すと何かしらの処理、例えば別々のサブVIを開くような、そんな状態を想定します。
これらのボタンを押すことでサブVIを実際に実行させること自体は主眼としてはいませんが、記事後半で一例を紹介しています。
プログラム実行中にマウスオーバーすると、そのボタンに対応した画面のプレビューを表示させることができます。
このプレビューは、表示させるサブVIの大きさに応じて画面のサイズが変わるようにしています。
プログラムの構造
プレビューを表示させる機能自体を専用のサブVIで実装させます。
マウスオーバーしたときやマウスの移動を行うといったイベントに対して処理がなされるように、複数のイベントを用意する必要があります。
また、マウスを動かした際にプレビューの画面も一緒に動くように、マウスの位置を取得するためのマウスを初期化関数をループに入る前に用意しています。
まずは、ブールボタンの値変更イベントです。
下の図の例では、イベントノードの「制御Ref」をプロパティノードのリファレンスに入力して、ラベルのテキストを取得し、そのテキスト名でどちらのボタンが押されたかを判定しています。
あとは、ケースストラクチャの中で、それぞれのボタンが押された際に行いたい処理を書きます。(下の図では特に何も実装はしていません)
次に、ブールボタンへのマウス境界内イベントです。ここで、あるフラグをTrueにしておきます。
このフラグは「マウスが境界外から境界内に入った」ことを示します。
次に、ブールボタンに対するマウス移動イベントです。
マウスがブールボタンの境界内に入ってさらにマウスがその境界内で動くときにこのイベントが実行され、まず最初に「サブVIのフロントパネルを表示させる機能を持ったサブVI」であるimage_viewer.viのリファレンスを非同期で開いています。
この非同期で開く動作は1回だけでいいので、先ほどマウス境界内のイベントで立てたフラグをFalseに戻します。
その後は後で紹介するimage_viewer.viに対してウィンドウのサイズを取得し、position_calc.viによって、表示させるウィンドウの位置をコントロールし、image_viewer.viのフロントパネルのウィンドウ境界プロパティに値を渡します。
こうすることで、Acquire Input Data.viで取得したマウス自体の位置に近い位置に常にウィンドウを表示させるようにしています。
実際にプレビューを呼び出すimage_viewer.viは、以下のようなフロントパネルをもちます。
ただし、フロントパネル上部にある、2Dピクチャ表示器以外の3つの物、文字列制御器と停止ボタンと数値のクラスタは、必ず2Dピクチャの上に置き、かつこのimage_viewer.viを閉じる際には2Dピクチャ表示器以外の部分は隠れるようにウィンドウのサイズを調整しておきます。
サイズを調整して以下の図の左にあるような見た目としたらOKです。
ブロックダイアグラムでは、アプリケーション制御の関数パレットにあるVIリファレンスを開くの関数で「プレビューを表示させたいサブVI」のリファレンスを開き、フロントパネルの画像を取得、これを2Dピクチャに表示させています。
2Dピクチャの表示はグラフィック&サウンドの関数の中のピクチャ関数を使用していますが、画像データにあるRectangleのクラスタを取得してこの値をsize表示器(先ほど、メインのVIのマウス移動イベント内で取得していたものがこれになります)に表示させ、かつ2Dピクチャの描画エリアサイズへの指定にも使用しています。
このimage_viewer.viは停止ボタンが押されるまで停止しませんが、この停止ボタンは後で紹介するメインVIのイベントで指定して「押される」ようにします。
なお、position_calc.viは以下のような実装としています。
下の図では、「10」が足されている部分がありますが、この数字を変更するとプレビューの表示位置を調整できます。
メインVIのイベントの説明に戻り、今度はブールボタンのマウス境界外イベントです。
つまり、マウスがブールボタンの領域から外れ、プレビューを表示する必要がなくなったときに発生するイベントで、このイベントからimage_viewer.viのstopボタンをTrueにして終了するようにしています。
イベントは以上のものを実装すれば完成です。
各サブVIを実行する場合
実際にボタンを押した際にサブVIを実行させる方法は一通りではないですが、イベントストラクチャの中で実行させるべきではないので、例えばキューを使って他のループで実行させるとか、非同期呼び出しにして実行するといった方法が考えられます。
今回はシンプルに、他のループで呼び出すようなキューを使った簡単な実装を例にします。
なおこの方法でサブVIを表示させる場合には、サブVIが呼び出されたときにサブVIのフロントパネルが表示される必要があります。
なので、サブVIそれぞれに対して以下のようにVIプロパティを設定し、呼び出されたらフロントパネルを表示するようにします。
なお、この書き方の場合、メインVIの方はこのサブVIの実行が終了しない限り操作できない(正確にはイベントの検出などは行いますが、デキューの関数がおかれたループはサブVIが終わるまでループが回らない)ので注意が必要です。
プレビューの表示非表示を切り替える
毎回プレビューを出すのはそれはそれで邪魔くさいかもしれないので、プレビューの表示非表示を切り替えるような仕組みが便利なときもあると思います。
切り替えには、スイッチ動作のブールボタンを置いて、ユーザーが任意に切り替えられるようにします。
ブールを追加することでワイヤが煩雑になることを防ぐために、複数のイベントで使用する設定(パラメタ)などは全てクラスタにまとめることで、よりプログラムをスッキリさせることができます。
クラスタでまとめた場合でも、全然構造を変える必要がないイベントも多くあります。
画面を表示するかどうかのブールの値の切り替え操作も、「画面を表示しない」ブールの値変更イベントでクラスタの値を更新することで、後のマウス移動イベントの際に参照できるようにしておきます。
マウス移動イベントについては無効かどうかの判定で全体をケースストラクチャで囲みます。
無効でない、つまりプレビューを表示させる場合の実装は既に紹介したとおりです。
注意点があるとすれば、クラスタでまとめたうちの「リファレンス出力」の部分は、以下の要領で「特定のVI(今回でいうimage_viewer.vi)」に対するリファレンスであることを固定するために、タイプ定義してやる必要があり、タイプ定義の中で「VIサーバクラスを選択」して、参照からimage_viewer.viを指定します。
タイプ定義を設定し終えたら、ファイルメニューから「変更を適用」を忘れないでください。
本記事では、マウスオーバーでプレビューを表示させる方法を紹介しました。
ヒントラベルのような手軽さで図を表示させる、といったことはできないのですが、専用のサブVIさえ用意してしまえばそこまで難しい話でもないと思うので、実装について参考にしてもらえればうれしいです。
ここまで読んでいただきありがとうございました。
コメント