2021年9月19日日曜日

64: PythonでUNOコンポーネントを作成する

<このシリーズの前の記事 | このシリーズの目次 | このシリーズの次の記事>

典型的には、マクロやLibreOfficeまたはOpenOfficeクライアントにおけるリスナー、例えばディスパッチコマンド群のための、しかし、それだけではない。

話題


About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice
About: Python

この記事の目次


開始コンテキスト



ターゲットコンテキスト



  • 読者は、自らのUNOコンポーネントをPythonにて作成・利用する方法を知る。

オリエンテーション


コンソールPython UNOクライアントを作成する方法の記事があります。

Pythonにて任意のUNOディスパッチコマンドを実行しその実行から全情報を取得する方法の記事があります。

LibreOfficeまたはOpenOfficeに外部Pythonを使用する方法の記事があります。

任意のユーザー/アプリケーション所有Pythonマクロを作成する方法の記事があります。

任意のドキュメント内Pythonマクロを作成する方法の記事があります。

Pythonマクロ群を格納する任意のLibreOfficeまたはApache OpenOffice拡張機能を作成する方法の記事があります。

あなたのPythonマクロに任意のモジュールをインポートする方法の記事があります。

あなたのプログラムから任意のマクロを呼び出す方法の記事があります。

任意のUNOインターフェイスを作成・登録し、当該マッピングイメージ群を生成する方法についての記事があります。


本体

ト書き
Hypothesizer 7、Objector 64A、Objector 64Bが、コンピューターの前にいる。


1: 動機


Hypothesizer 7
UNOコンポーネントを作成しようとする根源的動機は、そのインスタンス(UNOオブジェクト)を別のプログラミング言語環境から操作できるようにすることです。

Objector 64B
それじゃあ、私には作る必要がないわ、だって、Pythonでしかプログラミングしないから。

Hypothesizer 7
2つの点においてそうではありません、マダム。第1に、私が「別のプログラミング言語環境」と言うとき、それは、'別の(プログラミング言語環境)'であって、'(別のプログラミング言語)環境'ではありません。

Objector 64B
はあ?何が違うわけ?

Hypothesizer 7
もしも、あるPythonマクロとあるコンソールPython UNOクライアントをお持ちであれば、あなたは2つのプログラミング言語環境をお持ちであることになるでしょう。

Objector 64B
. . . もしも、2つのPythonマクロを持ってたら . . .

Hypothesizer 7
その場合は、ただ1つのプログラミング言語環境をお持ちだということになります。

Objector 64B
ああ、それじゃあ、私には作る必要はないわ、どっちみち!

Hypothesizer 7
. . . 第2に、問題は、あなた自身のプログラムだけのことではありません。あなたのプログラムは通常、LibreOfficeまたはApache OpenOffice本体に接続しますが、それは、別のプログラミング言語環境です。

Objector 64B
だから?私がLibreOfficeを作ったわけじゃないわ。

Hypothesizer 7
あなたがそれを作成したか否かに関わらず、それは、全体像の中の一部としてそこにあります。

Objector 64B
. . . それで、なんで、LibreOfficeは私のプログラムにちょっかい出したいわけ?

Hypothesizer 7
LibreOfficeは特にちょっかい出したいわけではありませんが、もしも、あなたのプログラムはLibreOfficeイベントたちの通知を受けたいというのであれば、使うべき主要メカニズムは、ブロードキャスター-リスナーパターンです。

Objector 64B
LibreOfficeはそのパターンで私のプログラムにちょっかい出さないといけないわけ?

Hypothesizer 7
あなたのプログラムは、あるリスナー(それはあなたのプログラム内に存在します)をあるブロードキャスター(それはLibreOffice本体内に存在します )へ登録し、そのブロードキャスターは、そのリスナーにイベントたちを通知しますが、ここで、通知するというのは、そのリスナーのあるメソッドをコールすることを意味します、したがって、そのリスナーは、LibreOffice本体から操作されることができなければならないわけです。

Objector 64B
. . . それじゃあ、私はUNOコンポーネントを作らないといけないわけ?残念だわ!

Hypothesizer 7
それは、特に残念ではありません。それは実に容易です。

Objector 64B
本当?容易なら何でもやるわ。

Hypothesizer 7
ただ容易だというだけで、悪いことをしないように願います。

いずれにせよ、お忘れないように願いたいのは、リスナーは典型的なケースですが、あなたは自由に他の種類の有用なUNOコンポーネントを考案して、そのインスタンスが別のプログラミング言語環境から操作されることができるようにできるということです。

Objector 64B
そういう「有用なUNOコンポーネント」はどのように使えるわけ?つまり、それらはどこへ登録できるの?

Hypothesizer 7
それらは、リスナーではないので、特に登録される必要はありません。例えば、あるUNOオブジェクトは、マクロのリターンになって、別のプログラミング言語環境内にいる呼び出し元から操作されることができます。


2: UNOサービスに関する注意


Hypothesizer 7
念を押しておきますが、私たちが話しているのは、UNOコンポーネントについてであって、UNOサービスについてではありません。

もしもそれらの区別がおできにならないのであれば、ある以前の記事をご参照ください。

Objector 64A
実のところ、私はUNOサービスについて話したいのだが。

Hypothesizer 7
ああ、サー、私が知る限りでは、Python UNOコンポーネントグローバルUNOサービスとして登録できません、その理由は、グローバルUNOサービス群マネージャーには、Pythonクラスをインスタンス化する能力がないからです。

Objector 64A
はあ?そいつは残念だ!

Hypothesizer 7
しかし、ご自分で、ご自身の非グローバルUNOサービス群マネージャー、またはもっと一般的なUNOオブジェクト群ファクトリを実装することはできます、お望みであれば。

Objector 64A
はあ?どうやって?

Hypothesizer 7
もしも、'com.sun.star.lang.XMultiComponentFactory' UNOインターフェイスを実装したUNOコンポーネントを作成なさったら、それは、UNOサービス群マネージャーでしょう。もしも、 もっと一般的なUNOオブジェクト群ファクトリをお望みであれば、ご自身のファクトリUNOインターフェイスを実装したUNOコンポーネント作成なさることができます。

勿論、あなたは、そのファクトリを何らかの方法でインスタンス化し、それをどこかに格納し、それを何らかの方法で公開しなければならないでしょう。

Objector 64A
「何らかの方法で」?どんな方法だ?

Hypothesizer 7
それを行なうマクロをあなたは用意することができます、例えば。

Objector 64A
「それを行なう」?どれを「行なう」のだ?

Hypothesizer 7
それは、そのファクトリをインスタンス化してそのインスタンスをそのファクトリクラスのあるスタティックメンバーに格納し(もしも、既にそうしてあるのでなければ)、そのスタティックメンバーからそのインスタンスをリターンします。

Objector 64A
ああ、それじゃあ、それは、3つのオペレーションを全て行なうのか、ファクトリのインスタンス化は最初のコール時においてのみ行なって。


3: 準備


Hypothesizer 7
もしも、あなたのUNOコンポーネントはいくつかのあなたのUNOインターフェイスを実装するというのであれば、それらは、ある以前の記事にしたがって既に作成済みである必要があります。

Python用のマッピングイメージたちは動的に生成されるので、あなたはそれらをコード内で生成することができます、その以前の記事内に記述されているとおり。.


4: UNOコンポーネントを作成する


Hypothesizer 7
以下は、UNOコンポーネントを作成する典型的なコードです。

@Python ソースコード
from typing import List
import uno
from com.sun.star.lang import XUnoTunnel
from unohelper import Base as UnoBase

class TestUnoComponent (UnoBase, XUnoTunnel):
	def __init__ (a_this: "TestUnoComponent") -> None:
		
		UnoBase.__init__ (a_this)
	
	def __del__ (a_this: "TestUnoComponent") -> None:
		None
	
	def getSomething (a_this: "TestUnoComponent", a_datumIdentification: List [int]) -> int:
		return 0

「XUnoTunnel」は、無害な例として使われているにすぎず、あなたは通常それを使う必要はありません。

Objector 64B
それじゃあ、私は何を使うべきなの?

Hypothesizer 7
あなたがUNOコンポーネント作成しようとされているのは、いくつかのUNOインターフェイスを実装なさりたいからであるはずです、したがってそれらをご使用になればよいのです。

Objector 64B
実のところ、今のところ何のUNOインターフェイスも実装したくないのよね。

Hypothesizer 7
それは、あなたは今のところ何のUNOコンポーネントも作成しようとされていないからです。もしも、あるリスナーを作成しようとされているのであれば、当該ブロードキャスターが求めるUNOインターフェイス群を実装したいと思われるでしょう。

Objector 64A
その「UnoBase」というのは何なのだ?

Hypothesizer 7
それは、実際には'unohelper.Base'(それに私がその別名を与えたのは、「Base」は一般的すぎて、他のモジュールと簡単に競合しかねないからです)ですが、あるUNOインターフェイス(具体的には、'com.sun.star.lang.XTypeProvider')を実装済みのヘルパークラスであり、もしも、あなたのUNOコンポーネントはそのUNOインターフェイスを実装する必要がないというのであれば、それは'unohelper.Base'を拡張する必要がありません、しかし、あなたのUNOコンポーネントはそれを実装するべきでないとする何らの理由も私は見出しません。

Objector 64B
私のUNOコンポーネントはそのUNOインターフェイスを必要とするの?

Hypothesizer 7
'XTypeProvider'は、それをマクロ言語環境からアクセス可能であるようにするためのものです。

Objector 64B
Pythonが既にマクロ言語環境だけど。

Hypothesizer 7
私たちが話しているのは、当該UNOコンポーネントのインスタンスを操作する、他のプログラミング言語環境についてです。

Objector 64B
例えば、LibreOffice本体のこと?

Hypothesizer 7
はい。

Objector 64B
それは、マクロ言語環境?

Hypothesizer 7
違います。したがって、もしも、LibreOffice本体へのリスナーを作成されているのであれば、そのUNOインターフェイスを実装する必要はありません。


5: 使用方法


Hypothesizer 7
そのUNOコンポーネントを格納しているモジュールファイルは、勿論、あなたのプログラムにインポートされなければなりません。

Objector 64B
「あなたのプログラム」ってどういう意味?つまり、どれのこと?別のプログラミング言語環境?

Hypothesizer 7
勿論違います: 別のプログラミング言語環境は、例えば、Java環境であって、それは、Pythonモジュールをインポートできません、当然ながら。

Objector 64B
それじゃあ、そのJava環境はどうやってそのUNOコンポーネントを使えるわけ?

Hypothesizer 7
UNOがどのように機能するかをご理解される必要があります。そのJava環境はそのUNOコンポーネントを認識しません。

Objector 64B
はあ?そのUNOコンポーネントは、認識もされずに、どうやってそのJava環境から活用できるの?

Hypothesizer 7
. . . 申し上げたとおり、UNOがどのように機能するかをご理解される必要があります。

Objector 64A
私のPythonマクロはどうやってそのUNOコンポーネントモジュールをインポートできるのだ?だって、恣意的なモジュールを私のマクロにただインポートするということはできない!

Hypothesizer 7
ある以前の記事をご参照ください、それを可能にするためには。

それはともかく、当該UNOコンポーネントの任意のインスタンスをあなたのプログラム内に生成するには、そのクラスのコンストラクタをコールすればよいだけです。

Objector 64B
はあ?サービスマネージャーをシャカシャカするとかのおまじないをする必要はないの?

Hypothesizer 7
UNOサービス群マネージャーは、UNOコンポーネントをリモート環境内にインスタンス化するためのものです。UNOサービス群マネージャーの動機を理解される必要があります。

Objector 64B
. . . それで、そのインスタンスはどう使えるの?

Hypothesizer 7
そのインスタンスはPythonオブジェクトなので、ローカル環境内ではそれを普通のPythonオブジェクトとしてお使いになれ、それをリモート環境へ、あるリモートUNOオブジェクトメソッドのある引数を介して渡すことができます。

Objector 64B
それで、そのリモート環境は、そのインスタンスをどのように操作できるの?

Hypothesizer 7
そのリモート環境は、そのインスタンスがどこにあるかは気にしません。したがって、それは、単にそのインスタンスがPythonUNOオブジェクトだからといって特別なことは何もしません。


参考資料


<このシリーズの前の記事 | このシリーズの目次 | このシリーズの次の記事>