ImageJ のPython スクリプトでインターアクティブな UI のプログラミングをやっていて、プレビューアーの中でプレビュー画面を作成したところ、プレビュー画面を閉じることができなくなってしまいました。
imagePlus を作成すると、グローバル変数と同じようにどこからでもアクセスできるはずですが、プレビューアーは def ではなく class として定義するためか、プレビューアーの中でプレビュー画面用の imagePlus を作成すると、他のモジュールからは直接アクセスできないようです。
以前、これをうまく切り抜ける対策を考えたと思いましたが、どうやったか記憶にありません。どのプログラムのコードにそれを応用したかも覚えていません。仕方ないのでもう一度一から考えることにしました。その方法をまたまた備忘録としてメモしておきます。
その前にまず、一般的な対策としては、
・プレビューアーの中で、表示用の imagePlus を作成せずに、事前に作成しておいて、プレビューアーを終了後に表示用の imagePlus を close() する
のが基本かと思います。例えば事前にプレビュー画面を表示する impPreview を作成しておき、
プレビューアーの中で、
class imagePreviewer(AdjustmentListener, ItemListener):
def __init__(self, impPreview, nfield_A, choice_B):
というように impPreview を引数として読み込んでおき、Previewer を使わなくなったところで、
impPreview.hide()
impPreview.close()
とやると、プレビュー用イメージがクローズされます。
ただ、プレビューアーの中でどうしてもプレビュー用の画像を新たに作成して表示する必要が出てくる場合があり、その場合、プレビューアーの中で close ができないので (プレビュー画面が途中で消える)、プレビューアーを終了した後、プレビューアーの外からどうやって、プレビューアーの中で作成したプレビュー用の imagePlus にアクセスするかということが問題になります。
結局思いついたのは、
・プレビューアーの中で、表示用の imagePlus を作成する場合は、その imagePlus に setTitle メソッドでタイトルをつけて置き、プレビューアー終了後、そのタイトルのついたウィンドウを、WM.getImage("タイトル")、を使って imagePlus に取得しておき、その imagePlus に対し、close() メソッドを実行する
※ この場合、ウィンドウマネージャーを WM という名前であらかじめインポートしておく
ということでした。
例えば、イメージプレビューアーの中で
self.impPreview というプレビュー表示用の imagePlus を作って、
self.impPreview.show() でプレビュー画像を表示します。
その際にself.impPreview.setTitle("Preview Image")
というように画像タイトルを指定しておきます。
そして、このプレビュー画像をプレビューアーの外からアクセスするときは、
impTemp = WM.getImage("Preview Image")
とコードを書いておくと、プレビューアーで作成しておいた imagePlus に対し、プレビューアーの外から、impTemp という名前でアクセスできるようになりますので、後は、
impTemp.hide()
impTemp.close()
でプレビュー画面を閉じることができます。