2022年10月9日日曜日

71: 任意のグローバルUNOサービスをPythonにて作成する

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

UNOコンポーネントをリモートプログラミング言語環境からインスタンス化するために、またはスプレッドシートセルファンクションなどの作成物を作成するために。

話題


About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice
About: Pythonプログラミング言語

この記事の目次


開始コンテキスト



ターゲットコンテキスト



  • 読者は、自らのグローバルUNOサービスをPythonにて作成する方法を知る。

オリエンテーション


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

本シリーズの任意のサンプルプログラムをビルドする方法についての記事があります。

UNOプログラムを開発するための、LinuxまたはWindows環境を構築するための記事があります。


本体

ト書き
Special-Student-7、Lenard(Pythonプログラマー)、Jane(Pythonプログラマー)がコンピュータの前にいる。


0: 私たちがここで"UNOサービス"によって意味するもの


Special-Student-7
私たちがここで"UNOサービス"によって意味するものは、ある記事にて説明されているものです。

簡潔に述べると、UNOサービスは、あるUNOオブジェクトたちファクトリ内のアイテムであり、そのファクトリは'UNOサービス群マネージャー'.と呼ばれます。

実のところ、"サービス"は、オフィシャル用語体系において、とても混乱してそして混乱させるように使われている用語であり、私たちは、"UNOサービス"によってオフィシャル用語体系における第2の意味も第3の意味も意味しません。

オフィシャル用語体系における第2の意味の"サービス"をどうすれば作成できるかを知りたいと思われているのであれば、私にはかなり確信がありますが、それはあなたが作成する必要のあるものではありません。

一部の人々はオフィシャル用語体系における第3の意味の"サービス"を便利とみなしているかもしれませんが、それも特にあなたが作成する必要のあるものではありません、そして、私は作成しないよう選択するので、それについて私は説明しません。


1: なぜUNOサービスが望まれるのか?


Special-Student-7
UNOサービスを作成する1つの目的は、リモートプログラミング言語環境から当該UNOコンポーネントをインスタンス化することです。

ご存知のとおり、ローカルプログラミング言語環境内では、UNOコンポーネントは通常のPythonクラスとしてインスタンス化できますが、リモートプログラミング言語環境からは、別の方法がなければなりません。

Jane
何が"ローカル"で何が"リモート"なのか分からないわ; ある場所は、私がその中にいれば"ローカル"であり、それを私が遠くから見ていれば"リモート"であって、何ものもそれ自体として特に"ローカル"でも"リモート"でもない; 単に私がどこにいるかの問題。

Special-Student-7
おっしゃるとおりです。ここでの"ローカル"が意味するのは、当該UNOコンポーネントがインスタンス化されるプログラミング言語環境を意味してます; この場合、あなたの所在地は関係ありません。

Lenard
でも、私のUNOコンポーネントは私のUNOオブジェクトたちの1つによってインスタンス化されることができる、ローカルだ、あなたの用語によれば。

Special-Student-7
しかし、あなたの最初のUNOオブジェクトはどこからか来なければなりません、そしてそれは典型的にはあるUNOサービスたちマネージャーから来るのです、それが意味するのは、その最初のUNOオブジェクトはUNOサービスインスタンスとして誕生するということ。

Lenard
でも、私は、自分のPythonマクロ(ローカル)に自分のPython UNOコンポーネントをインスタンス化させて、そのマクロがリモートプログラミング言語環境から呼ばれるようにできる。

Special-Student-7
ああ、おっしゃるとおりです; それは1つの方法です、確かに。

したがって、UNOサービスは、UNOコンポーネントをリモートプログラミング言語環境からインスタンス化する1つの方法です、唯一の方法ではなく。

私が知る限り、Python UNOサービスを作成する、より広く存在する動機は、UNOサービスの定義を求める生成物を作成することです。

Jane
"作成物"?あなたが何について話しているのか分からないわ。

Special-Student-7
"作成物"というのは、例えば、スプレッドシートセルファンクションで、それは、実のところあるUNOコンポーネントの1メソッドであり、そのUNOコンポーネントはUNOサービスとしてオフィス本体からインスタンス化されます。

Jane
すると、UNOサービスを作成する方法を知る必要があるわけね、もしも、スプレッドシートセルファンクションを作成する必要があれば . . .

Special-Student-7

2: 注意: 私たちはグローバルUNOサービスを作成します


Special-Student-7
全てのUNOサービスグローバルUNOサービスであるわけではありませんが、私が本記事内でUNOサービスについて話すときは、私は常にグローバルUNOサービスについて話しています。

Lenard
おお、残酷な世界だ!非グローバルUNOサービスたちは無視されている!

Special-Student-7
任意の非グローバルUNOサービスはオフィスプロダクトによる内部使用のためだけのものです、私が知る限り、したがって、あなたには多分、非グローバルUNOサービスを作成する機会、もしくは非グローバルUNOサービスを直接使用する機会すら、全くないでしょう。

Lenard
ないの?

Special-Student-7
多分ないでしょう。したがって、注意として、私がUNOサービスについて本シリーズ内で特別な指定なしに話すときは、それはグローバルUNOサービスについてです。


3: UNOサービスを作成する



3-1: UNOコンポーネントを用意する


Special-Student-7
当該UNOコンポーネントは、それがUNOサービスとして登録されるためには、特定の要件を満たしていなければなりません。

具体的には、それは、'com.sun.star.lang.XServiceInfo' UNOインターフェイスを実装していなければなりません、以下のように。

@Python ソースコード
from typing import Any
from typing import List
from typing import Set
from typing import cast
from collections import OrderedDict
import uno
from com.sun.star.lang import IllegalArgumentException
from com.sun.star.lang import XServiceInfo
from com.sun.star.uno import XComponentContext
from unohelper import Base as UnoBase
XTest1: Any = uno.getClass ("theBiasPlanet.unoDatumTypes.tests.XTest1")

class PythonTest1UnoComponent (UnoBase, XServiceInfo, XTest1):
	c_thisClass: type = None
	c_unoServiceNames: Set [str] = set ()
	c_unoCompoundInterfaceNames: Set [str] = set ()
	# # Add UNO service names Start
	c_unoServiceNames.add ("theBiasPlanet.tests.PythonTest1UnoComponent")
	# # Add UNO service names End
	# # Add UNO compound interface names Start
	# # Add UNO compound interface names End
	
	@staticmethod
	def setThisClassToGlobalUnoServicesProvider (a_implementationClassNameToImplementationClassToUnoServiceNamesMapMap: "OrderedDict [str, OrderedDict [type, Set [str]]]")-> None:
		l_implementationClassToUnoServiceNamesMap: "OrderedDict [type, Set [str]]" = OrderedDict ()
		l_implementationClassToUnoServiceNamesMap.update ( {PythonTest1UnoComponent.c_thisClass: PythonTest1UnoComponent.c_unoServiceNames})
		a_implementationClassNameToImplementationClassToUnoServiceNamesMapMap.update ( {"{0:s}.{1:s}".format (PythonTest1UnoComponent.c_thisClass.__module__, PythonTest1UnoComponent.c_thisClass.__name__): l_implementationClassToUnoServiceNamesMap})
	
	def __init__ (a_this: "PythonTest1UnoComponent", a_underlyingUnoObjectsContextInXComponentContext: XComponentContext, a_message: str) -> None:
		a_this.i_underlyingRemoteUnoObjectsContextInXComponentContext: XComponentContext
		# # Add the other member variables Start
		a_this.i_message: str
		# # Add the other member variables End
		
		UnoBase.__init__ (a_this)
		a_this.i_underlyingRemoteUnoObjectsContextInXComponentContext = a_underlyingUnoObjectsContextInXComponentContext
		a_this.i_message = None
		
		# initialization Start
		a_this.i_message = a_message
		if a_this.i_message is None:
			raise IllegalArgumentException ("The first argument can't be null.")
		# initialization End
	
	def __del__ (a_this: "PythonTest1UnoComponent") -> None:
		None
	
	def getImplementationName (a_this: "PythonTest1UnoComponent") -> str:
		return "{0:s}.{1:s}".format (PythonTest1UnoComponent.c_thisClass.__module__, PythonTest1UnoComponent.c_thisClass.__name__)
	
	def supportsService (a_this: "PythonTest1UnoComponent", a_unoCompoundInterfaceName: str) -> bool:
		return a_unoCompoundInterfaceName in PythonTest1UnoComponent.c_unoCompoundInterfaceNames
	
	def getSupportedServiceNames (a_this: "PythonTest1UnoComponent") -> List [str]:
		l_numberOfItems: int = len (PythonTest1UnoComponent.c_unoCompoundInterfaceNames)
		l_unoCompoundInterfaceNamesArray: List [str] = [None] * l_numberOfItems
		l_itemIndex: int = 0
		l_unoCompoundInterfaceName: str = None
		for l_unoCompoundInterfaceName in PythonTest1UnoComponent.c_unoCompoundInterfaceNames:
			l_unoCompoundInterfaceNamesArray [l_itemIndex] = l_unoCompoundInterfaceName
			l_itemIndex = l_itemIndex + 1
		return l_unoCompoundInterfaceNamesArray
	
	# # Add the methods of the implemented UNO interface Start
	def test1 (a_this: "PythonTest1UnoComponent", a_name: str)-> str:
		if a_name is None:
			raise IllegalArgumentException ("The first argument can't be null.")
		return "{0:s}, {1:s}!".format (a_this.i_message, a_name)
	# # Add the methods of the implemented UNO interface End
	
	# # Add other methods Start
	# # Add other methods End

PythonTest1UnoComponent.c_thisClass = PythonTest1UnoComponent

Lenard
. . . もちろん . . .

Special-Student-7
勿論、それを厳密にそのとおりに実装される必要はありません: そのコンストラクタとそれらの'XServiceInfo'メソッドたちを何らかの形で適切に実装される必要があります。

Lenard
"何らかの形で"?どんな形で?

Special-Student-7
そのコンストラクタは、その'XComponentContext'引数をそこに持たなければならず、適切な初期化引数たちを持たなければなりません。

Python UNOは、'com.sun.star.lang.XInitialization' UNOインターフェイスが実装されても顧みないという点で特殊です。

Lenard
はあ?

Special-Student-7
Java UNOおよびC++ UNOでは、UNOサービス UNOコンポーネントは、'com.sun.star.lang.XInitialization' UNOインターフェイスを実装しなければならず、初期化引数たちは、UNOインターフェイスの'initialize'メソッドへ渡されます。

Python UNOでは、初期化引数たちは、コンストラクタへ渡されます。

Lenard
複数の引数たちがあったらどうなんだ?

Special-Student-7
コンストラクタは複数の引数たちを持たなければなりません。

Lenard
それじゃあ、引数たちの数はあらかじめ決められていないといけないと . . .

Special-Student-7
はい。その状況は、引数たちは配列として渡される他のUNOプログラミング言語たちとは異なります。

Lenard
えーと . . .

Special-Student-7
"supportsService"および"getSupportedServiceNames"にとっての"service"は、基本的にはUNOサービスではなく、オフィシャル用語体系における第2の意味の"サービス"です。

Jane
それで、どの第2の意味"サービス"たちを当該UNOコンポーネントはサポートする必要があるの?

Special-Student-7
もしも、UNOコンポーネントがある種の作成物のものであれば、その種類は、そのUNOコンポーネントが特定の"サービス"たちをサポートすることを要求します; さもなければ、そのUNOコンポーネントはなんらの"サービス"もサポートする必要はありません、基本的には。

Jane
非"基本的には"どうなの?

Special-Student-7
"サービス"はコンセプトとしてとてもまぜこぜにされてしまっているので、時折、基本的にはオフィシャル用語体系における第2の意味の"サービス"であるものが節操なくUNOサービスの意味においても乱用されており、その逆もあります。それら2つのメソッドでUNOサービス名をサポートしなくて何らの問題にも私は気付いたことはありませんが、私が"基本的には"と言ったのは念の為です。実のところ、そこでUNOサービス名をサポートしても実際的問題はないでしょうし、それを選択されてもよいでしょう。

Jane
ああ、大人の話ね。

Special-Student-7
UNOサービス情報を"c_unoServiceNames"等の中に管理するのは、そうした情報を複数メソッドに散らばせないための私の手立てであって、あなたは特にしたがう必要はありません; また、"setThisClassToGlobalUnoServicesProvider"メソッドは情報をグローバルUNOサービス群プロバイダー(次に作成されます)へ注入するためのものであり、情報を重複してグローバルUNOサービス群プロバイダーへ書くことを避ける目的のものです、したがって、あなたはそのメソッドを持つ必要は特にありません、もしも重複して書きたいというのであれば。


3-2: グローバルUNOサービス群プロバイダーを作成する


Special-Student-7
私たちはグローバルUNOサービス群プロバイダーを作成しなければなりません、それは、UNOサービスたちがインスタンス化されるために求められます。

実のところ、PythonグローバルUNOサービス群プロバイダーは、JavaグローバルUNOサービス群プロバイダーとは違ってクラスではなく、'g_ImplementationHelper' 'unohelper.ImplementationHelper'オブジェクトを持つモジュールです。

Lenard
うむ?それじゃあ、それは、1つのオブジェクトを持つというだけの話のもの?

Special-Student-7
はい、そうです。

Lenard
それじゃあ、単にUNOコンポーネントにそのオブジェクトを持たせられないわけ?

Special-Student-7
そうすることは可能ですが、複数のUNOコンポーネントたちがあるかもしれないのに、どれがそのオブジェクトを持つべきなのですか?

Lenard
任意の恣意的な1つが持つべき。

Special-Student-7
私は、そのような非対称性を肯定しませんが。

Lenard
でも、私は1つだけしかUNOコンポーネントを持ってない。

Special-Student-7
もしも、たまたま1つしかUNOコンポーネントを持っていないとしても、情報構造は既に歪められているということになります、なぜなら、オブジェクトは本当にはそこに属しないのですから。

Lenard
そうかな?

Special-Student-7
いずれにせよ、以下はグローバルUNOサービス群プロバイダーであり、その後のは、私のユーティリティクラスです。

@Python ソースコード
from typing import Any
from typing import Set
from collections import OrderedDict
import uno
import unohelper
from theBiasPlanet.unoUtilities.servicesHandling.GlobalUnoServicesProviderUtility import GlobalUnoServicesProviderUtility
from theBiasPlanet.tests.models.PythonTest1UnoComponent import PythonTest1UnoComponent

c_implementationClassNameToImplementationClassToUnoServiceNamesMapMap: "OrderedDict [str, OrderedDict [type, Set [str]]]" = OrderedDict ()
PythonTest1UnoComponent.setThisClassToGlobalUnoServicesProvider (c_implementationClassNameToImplementationClassToUnoServiceNamesMapMap)
g_ImplementationHelper: Any = unohelper.ImplementationHelper () # this variable has to be of the name, because the office product searches for it.
GlobalUnoServicesProviderUtility.setUpUnoServiceRegistrationHelper (g_ImplementationHelper, c_implementationClassNameToImplementationClassToUnoServiceNamesMapMap)


@Python ソースコード
from typing import Any
from typing import Set
from collections import OrderedDict

class GlobalUnoServicesProviderUtility:
	@staticmethod
	def setUpUnoServiceRegistrationHelper (a_unoServiceRegistrationHelper: Any, a_implementationClassNameToImplementationClassToUnoServiceNamesMapMap: "OrderedDict [str, OrderedDict [type, Set [str]]]")-> None:
		l_implementationClassName: str = None
		l_implementationClassToUnoServiceNamesMap: "OrderedDict [type, Set [str]]" = None
		l_implementationClass: type = None
		l_UnoServiceNames: Set [str] = None
		for l_implementationClassName, l_implementationClassToUnoServiceNamesMap in a_implementationClassNameToImplementationClassToUnoServiceNamesMapMap.items ():
			for l_implementationClass, l_UnoServiceNames in l_implementationClassToUnoServiceNamesMap.items ():
				break
			a_unoServiceRegistrationHelper.addImplementation (l_implementationClass, l_implementationClassName, tuple (l_UnoServiceNames))


私がそのユーティリティクラス"GlobalUnoServicesProviderUtility"を用意した理由は、そのコードを各グローバルUNOサービス群プロバイダー内に書くのは不経済であることです、しかし、もしも望まれるのであれば、勿論、あなたは不経済にすることができます。

前サブセクションで申し上げたとおり、UNOサービスの情報はグローバルUNOサービス群プロバイダーへ"setThisClassToGlobalUnoServicesProvider"によって注入される。

Jane
えーと、あなたはコードを必要以上に複雑にしたようだけど: "setThisClassToGlobalUnoServicesProvider"メソッドに情報を直接に'g_ImplementationHelper'オブジェクトへ入れさせられるでしょう、そうすれば、そんなユーティリティクラスは不必要でしょう。

Special-Student-7
ああ、そのとおりです、実は。

Jane
"そのとおりです"?それだけ?

Special-Student-7
つまり、おっしゃることは理解できるということです: あなたのコードは全体としてずっと短くてすむでしょう。私のコードがそのようであるのは、各UNOコンポーネントは'g_ImplementationHelper'オブジェクトの実装に依存しないほうがよいと考えたからです。


3-3: 拡張機能コンフィグレーションファイルたちを作成する


Special-Student-7
私たちは、当該UNOサービスをあるLibreOfficeまたはApache OpenOffice拡張機能を介して登録しようとしており、そのためには、いくつかのコンフィグレーションファイルたちが必要です。

Lenard
自分が"拡張機能"を作成しようとしているとは知らなかった。

Special-Student-7
サー、それは、いくつかのコンフィグレーションファイルたちを作成し、内容物たちをあるZIPファイル内にアーカイブするというだけの簡単なことです

Lenard
なるほど。

Special-Student-7
私たちはその"UnoServiceComponents.xml"ファイルを作成します、以下のように。

@XML ソースコード
<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://openoffice.org/2010/uno-components">
	<component loader="com.sun.star.loader.Python" uri="Scripts/python/theBiasPlanet/tests/globalUnoServicesProvider/TestsGlobalUnoServicesProvider.py">
		<!-- # Add UNO component class names -->
		<implementation name="theBiasPlanet.tests.models.PythonTest1UnoComponent.PythonTest1UnoComponent">
			<!-- # Add UNO service names Start -->
			<service name="theBiasPlanet.tests.PythonTest1UnoComponent"/>
			<!-- # Add UNO service names End -->
			<!-- # Add UNO compound interface names Start -->
			<!-- <service name="???"/> -->
			<!-- # Add UNO compound interface names End -->
		</implementation>
	</component>
</components>

Jane
そのタグ名は"component"だけど、UNOコンポーネントには対応してないよね?

Special-Student-7
はい、していません。"component"は、しまりのないオフィシャル用語体系では何物をも意味する可能性があり、この場合は、"component"は拡張機能内に定義された複数かもしれないPython UNOサービスたちの集合を意味しているようです。

Jane
いずれにせよ、そうすることによって、グローバルUNOサービス群プロバイダーはオフィスプロダクトに認識されるということなのね。

Special-Student-7
注意として、そこでは、UNOサービス名も指定されるべきです、第2の意味における"サービス"名たちが指定されるべきだけでなく。

Lenard
はあ?あれら2メソッドたちはUNOサービス名をサポートする必要ないのに、なんで、そのコンフィグレーションファイルはUNOサービス名を必要とするわけ?

Special-Student-7
あなたはそのような一貫性のなさを辛抱しなければなりません; "サービス"は実際のところコード中でごちゃまぜになっています、ドキュメント中だけでなく。

いずれにせよ、私たちは、勿論、"manifest.xml"も作成しなければなりません、しかし、それをここでは示しません、なぜなら、それはその記事内におけるのと全く同じだからです。


3-4: 余談: 必要でないもの


Lenard
例のサービスIDLファイルを作成する必要があるよね?

Special-Student-7
いいえ、なぜなら、任意のサービスIDLファイルはしまりのないオフィシャル用語体系における第2の意味における"サービス"または第3の意味における"サービス"を作成するためのものであって、UNOサービスを作成するためのものではないからです。

あなたは第2の意味における"サービス"を作成する必要は決してないでしょう; あなた、Pythonプログラマー、は、なんらの第3の意味における"サービス"を使うことができません、なぜなら、それのPythonイメージを生成するツールがありませんから、もっとも、Javaプログラマーはそれを使ってあなたのPython UNOサービスをインスタンス化することができますが。

Lenard
でも、それで私の心の平安がいくらか得られるんだが。

Special-Student-7
えーと、なぜ、あなたはその心の平安というのをただ持たないのですか、無意味なものを作成することなしに?


3-5: 拡張機能ファイルを作成する


Special-Student-7
それでは、拡張機能ファイルを作成しましょう。

私は方法を説明する必要はありません、なぜなら、それは、既にある以前の記事内に詳述されていますので。


3-6: 拡張機能を登録する


Special-Student-7
拡張機能を登録しましょう。

それは、GUIメニュー項目"Tools(ツール)" -> "Extension Manager...(拡張機能)"を介して行なえます。

または、'unopkg'コマンドをお使いになることもできます、もしも、ご自身のビルドスクリプトで拡張機能を登録されたいのであれば、以下のように。

@bash or cmd ソースコード
unopkg add -f -v %the extension file path%

注意として、LibreOfficeまたはApache OpenOfficeインスタンスはそのコマンドの前にシャットダウンされているように想定されています。


3-7: 追加のモジュールたちパスたちをオフィスプロダクトへセットする


Special-Student-7
私たちはUNOコンポーネントグローバルUNOサービス群プロバイダーを2つの異なるモジュール内に作成しましたが、実のところ、その構造はあるコンフィグレーションを必要とし、それなしでは、グローバルUNOサービス群プロバイダーはUNOコンポーネントをインポートできません。

実のところ、拡張機能Pythonベースディレクトリのパスは自動的にはオフィスプロダクトへ登録されません。

Lenard
はあ?馬鹿げてる?それじゃあ、私の拡張機能内の任意のマクロは同一拡張機能内のモジュールを全然インポートできないじゃないか!

Special-Student-7
できません、コンフィグレーションなしでは、実際のところ。

Lenard
それじゃあ、私はマクロを自足にしなければならない、依存されるコードを全部そのマクロモジュールに押し入れて、馬鹿げてる!

Special-Student-7
はい、当該コンフィグレーションが設置されていなければ、別の記事のあるセクションに説明されているように。

Lenard
そのコンフィグレーションはオフィスプロダクトに組み込まれるべきだと思うが。

Special-Student-7
どうかその主張を唱導してください。

もしも、あなたはそのコンフィグレーションをしないというのであれば、当該UNOコンポーネントはグローバルUNOサービス群プロバイダーモジュール内に押入れられなければならないでしょう。

そして、もしも、あなたが作成したかなにかのいくつかのライブラリたちをあなたのUNOサービスが使用しているというのであれば、そのライブラリたちのパスたちはオフィスプロダクトへセットされなければなりません。

Lenard
それらのライブラリたちを単にPythonプロダクト自体に登録するというのではいけないのか?

Special-Student-7
そうすることもできます; 例えば、'pip'でインストールされた任意のライブラリは確かにPythonプロダクトの一部であって、そのパスたちはオフィスプロダクトへ明示的にセットされる必要はありません。

しかし、あなたは通常、あなたが作成したライブラリをPythonプロダクトへ登録しないでしょう?

Lenard
しない、もしも必要でなければ。

Jane
ライブラリたちを拡張機能内へコピーしてもいいんでしょう、当該コンフィグレーションを設置した後で?

Special-Student-7
はい、そうできます、しかし、ライブラリたちを複数の拡張機能へコピーすると、それらライブラリたちが重複してしまいますので、私であれば、ライブラリたちをローカルファイルシステム内に配置して、パスたちをオフィスプロダクトへセットするでしょう、例の記事の別のセクションで説明された方法によって、ライブラリたちが複数拡張機能やらなにやらに共有されるにして。

Jane
ふーむ。


4: UNOサービスをインスタンス化する


Special-Student-7
UNOサービスは、任意のビルトイングローバルUNOサービスと同じようにインスタンス化することができます。

Jane
上記UNOサービスがどうすればインストール化できるかを見せてちょうだい。

Special-Student-7
例えば、以下はPythonマクロです。

@Python ソースコード
from typing import Any
from typing import cast
import uno
~
from com.sun.star.script.provider import XScriptContext
from com.sun.star.uno import XComponentContext
XTest1: Any = uno.getClass ("theBiasPlanet.unoDatumTypes.tests.XTest1")

XSCRIPTCONTEXT: XScriptContext
c_underlyingRemoteUnoObjectsContextInXComponentContext: XComponentContext = XSCRIPTCONTEXT.getComponentContext ()
~
c_pythonTest1UnoComponent: "XTest1" = cast (XTest1, c_underlyingRemoteUnoObjectsContextInXComponentContext.getServiceManager ().createInstanceWithArgumentsAndContext ("theBiasPlanet.tests.PythonTest1UnoComponent", ["Hello"], c_underlyingRemoteUnoObjectsContextInXComponentContext))
~

def test1 () ->None:
	~
	c_pythonTest1UnoComponent.test1 ("dude")
	~


Jane
ふーむ、今や、そのPythonクラスはどんなリモートUNOプログラミング言語環境からもインスタンス化できるわけね。


5: ここに動かせるサンプルがあります


Special-Student-7
ここに、動かせるサンプル拡張機能があります

そのサンプルプロジェクトをビルドする方法はある記事に説明されています。

メインプロジェクトは'hiUnoExtensionsUnoExtension'で、それはいくつかのユーティリティプロジェクトたちおよび付加UNOデータタイプたちプロジェクトを使用しています。

UNOデータタイプたちマージされたファイルはオフィスプロダクトへ登録されなければなりません、ある以前の記事に述べられた方法1)にしたがって。

そして、ユーティリティPythonコードベースディレクトリたち('coreUtilitiesToBeDisclosed/target'および'unoUtilitiesToBeDisclosed/target')のパスたちがオフィスプロダクトへセットされなければなりません、ある以前のセクション内で言及された方法にしたがって。

Lenard
教育されていないユーザーたちにそんなことができると私は期待しないが、拡張機能はそういうユーザーたちに配布される想定なのに。

Special-Student-7
UNOデータタイプたちマージされたファイルのセッティングは不要化することができます、ある以前の記事内に述べられた方法2)によりUNOデータタイプたちマージされたファイルを拡張機能内へ入れることによって、しかし、ユーティリティライブラリたちに関わる状況は以前のセクション内で述べられたとおりです。

Lenard
でも、ユーザーたちがセッティングをできなければ無意味だ。

Special-Student-7
それは、セッティングを自動化するインストーラーをあなたがどのように準備するかの問題です、そして、もしも、あなたのUNOコンポーネントが自己充足であれば、あなたはライブラリたちについて心配する必要はないでしょう。

Lenard
えーと、私はインストーラーを用意することはできる、ただいくつかのファイルたちをコピーしないといけないというだけだからね、オフィスプロダクトディレクトリパスが事前に分かっている想定すれば。

Jane
あなたのインストーラーは単にユーザーにディレクトリパスを尋ねればいいのよ。

Special-Student-7
とにかく、当該拡張機能は、あるツールボタンたちグループを登録したはずであり、それからテストマクロをコールすることができます。

Lenard
"ボタンたち"?私は複数ボタンたちを得るわけ?

Special-Student-7
Python UNOサービス用ボタンは1つだけです; 他2つのボタンたちはJava UNOサービス用およびC++ UNOサービス用であり、それらは使用不能です、もしも、サンプルプロジェクトをビルドするのにあなたがJavaおよびC++を無効にしていたら。


参考資料


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