LibreOffice5(81)Javaの例:GUIをPythonにする その7

2017-09-08

旧ブログ

t f B! P L
ImageControlSample.javaをPythonにします。ファイル選択ダイアログで表示される画像を変更できるようにしました。
(2017.11.12追記。「ファイルフィルター」という用語を「表示フィルター」に変更しました。LibreOffice5(93)ファイルフィルターのダイアログ(UIComponent)の一覧を取得参照。)

前の関連記事:LibreOffice5(80)Pythonでcom.sun.star.util.Colorの値を変換する方法


imagecontrolsample.py: 画像をダイアログに表示する


GUI/imagecontrolsample.py at 5f5cab04ffba1dc4ca3171a66bfbb948629b9931 · p--q/GUI


 UnoControlDialogサービスでダイアログを作成しています。

 Javaの例では特定の画像を表示するだけでしたが、FilePickerサービスを使って表示する画像をファイルをダイアログから選択できるようにしました。

FilePickerサービスを使っているためオートメーションで実行するとクラッシュします。

FilePickerサービスをインスタンス化した時点で必ずしもクラッシュするわけではないので、デバッグ目的でオートメーションは利用できます。

BrowseボタンをクリックするとEdtiコントロールで表示しているパスのフォルダをデフォルトフォルダとしてファイル選択ダイアログが開きます。

ファイル選択ダイアログで使う表示フィルターはLibreOffice5(68)画像フィルターリストの作成で作成したものを使っていますが、本当にすべてのファイル形式に対応しているかは確認していません。

表示フィルターはappendFilter()メソッドで追加した順に表示されるので、表示フィルター名で わざわざアルファベット順で並び替えてから追加しています。

実際にプログラムに組むこむときは予め並び替えたリテラルの方が効率がよいのですが、Pytyonの辞書は順番が保証されないので何か工夫しないといけません。

FilePickerのテンプレートは可能なとき(LibreOffice5.3以上)はFILEOPEN_PREVIEWを使いますが、使えない時はFILEOPEN_SIMPLEを使います。

LibreOffice5(77)FilePickerのTemplateDescriptionを実行してみるでみたようにWindows10では FILEOPEN_PREVIEWもFILEOPEN_SIMPLEでも違いはないはずです。

imagecontrolsample.pyで使用している汎用関数


新たなものはありませんが、すこし変更しました。

enableRemoteDebugging()

この関数はEclipse: PyDevメモ: LibreOfficeのPythonマクロのデバッグで作成したマクロのデバッグ用のコードです。

import pydevd とするだけで結構な時間がかかることがわかったので、インポートする位置をあとにずらしました。

dialogCreator()のaddControl()

この関数はLibreOffice5(69)Javaの例:GUIをPythonにする その2で作成したもので、クロージャのUnoControlDialogにコントロールを追加しますが、追加したコントロールを戻り値にしました。

リスナーを使うときにリスナーにコントロールを渡さないといけない時が多いからです。

 imagecontrolsample.pyでは戻り値を使用していないので属性を利用していないコントロールについてはわざわざgetControl()でコントロールを無駄に取得していることになりますけど。

imagecontrolsample_taskcreator.py: サイズ変更可能なダイアログ


GUI/imagecontrolsample_taskcreator.py at 456bda6f9d2d560afd682c41c4a2dfff4060fc0c · p--q/GUI


(2017.9.11追記。Windows10ではFilePicker Service Referenceに書いてある通りFilePickerサービスを毎回インスタンス化しないとファイル選択ダイアログが表示されませんでした。imagecontrolsample.pyではそんなことしなくてもよかったのですが、、、
GUI/imagecontrolsample_taskcreator_forWin.py at 61951d509534d9101d545451d0f0cfa2bd1f591c · p--q/GUI
これでWindows10でもファイル選択ダイアログが表示されるようになりました。BrowseボタンをクリックするたびにFilePickerサービスをインスタンス化して表示フィルターを追加しているのでダイアログが表示されるまで少し時間がかかります。)

 先ほどのUnoControlDialogサービスで作成したダイアログと違ってダイアログウィンドウの下縁のデザインが異なっています。

ウィンドウの下縁にマウスカーソルを持ってくるとダイアログの大きさの変更ができます。

Windows10の場合はサイズ変更可能かどうかは見た目ではわかりません(LibreOffice5(79)ダイアログとコントロールコンテナの背景色参照)。

UnoControlDialogModelにはSizeableというプロパティがちゃんとあるのですが、これをTrueにしてもUnoControlDialogはサイズ変更できません(Dialog with "Sizeable" property set is not sizeable. (View topic) • Apache OpenOffice Community Forum)。

なのでTaskCreatorサービスで作成したウィンドウを使っています。

この方法で作成できるのはモダルウィンドウのみです(LibreOffice5(58)モードレスダイアログの例をPythonに翻訳する:その4参照)。

ウィドウのサイズは変更できますが、コントロールは変化しません。

ウィンドウサイズに合わせてコントロールを変化させるにはXWindowListenerインターフェイスを実装しないといけません。

コントロールのサイズ変更については次の記事でやります。

imagecontrolsample_taskcreator.pyで使用している汎用関数


これも新たなものはありませんが、すこし変更しました。

controlcontainerCreator()のaddControl()

先ほど出てきたdialogCreator()のaddControl()と同様にコントロールを戻り値にしています。

dialogCreator()のaddControl()ではコントロールモデルは、UnoControlDialogModelサービスのcreateInstance()でコントロールモデルをインスタンス化しているのに対して、controlcontainerCreator()のaddControl()では、UnoControlContainerModelサービスにはそのようなメソッドはないので、サービスマネージャーのcreateInstanceWithContext()でコントロールモデルをインスタンス化しています。

なので、dialogCreator()のaddControl()とcontrolcontainerCreator()のaddControl()ではコントロールの追加の仕方が違っています。

dialogCreator()のaddControl()の場合(ma単位を使う場合)

UnoControlDialogModelのインスタンス化
→UnoControlDialogのsetModel()でUnoControlDialogModelをセットする
→UnoControlDialogModelのcreateInstance()でコントロールモデルをインスタンス化
→コントロールモデルをUnoControlDialogModelのinsertByName()で挿入。

これでコントロールをインスタンス化しなくてもUnoControlDialogからgetControl()でコントロールを取得できるようになります。

dialogCreator()のaddControl()の場合(ピクセル単位を使う場合)

ピクセル単位を使うときはコントロールモデルではなくコントロールに位置や大きさを設定しないといけないので以下のようになります。

UnoControlDialogModelのインスタンス化
→UnoControlDialogのsetModel()でUnoControlDialogModelをセットする
→UnoControlDialogModelのcreateInstance()でコントロールモデルをインスタンス化
→サービスマネージャーのcreateInstanceWithContext()でコントロールをインスタンス化
→コントロールのsetModel()でコントロールモデルをセットする
→コントロールをUnoControlDialogのaddControl()で挿入。


ちなみにUnoControlDialogサービスで作成した最初のダイアログを単位だけをma単位からピクセル単位に変更したらこんなちっちゃなダイアログになりました。

ma単位はダイアログエディタ用の単位で、システムフォントの平均サイズの高さの1/8、幅の1/4を、各方向の1単位としているので、そのままの数値をピクセル単位に使うと小さくなってしまいます(LibreOffice5(58)モードレスダイアログの例をPythonに翻訳する:その4参照)。

ma単位を使っているimagecontrolsample.pyからピクセル単位のimagecontrolsample_taskcreator.pyに変換するにあたっては、いちいち画像をキャプチャしてピクセルを測定して変換しています。

ma単位のダイアログにピクセル単位のコントロールを載せることもできました。

controlcontainerCreator()のaddControl()の場合

UnoControlContainerのインスタンス化
→UnoControlContainerのsetModel()でUnoControlContainerModelをセットする
→サービスマネージャーのcreateInstanceWithContext()でコントロールモデルをインスタンス化
→サービスマネージャーのcreateInstanceWithContext()でコントロールをインスタンス化
→コントロールのsetModel()でコントロールモデルをセットする
→コントロールをUnoControlContainerのaddControl()で挿入。

コントロールをインスタンス化しないといけないので、dialogCreator()のaddControl()よりもステップが多くなっています。

その代わりaddControl()の戻り値にコントロールを返すのは、すでにインスタンス化してあるコントロールを単に返すだけです。

参考にしたサイト


Dialog with "Sizeable" property set is not sizeable. (View topic) • Apache OpenOffice Community Forum
UnoControlDialogサービスで作成したダイアログの大きさを変更可能にはできませんでした。

次の関連記事:LibreOffice5(82)Javaの例:GUIをPythonにする その8

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ