wxPythonを使用します。テキストフォーマットだけではありません。多くのフォーマットがサポートされます。
話題
About: Pythonプログラミング言語
この記事の目次
- 開始コンテキスト
- ターゲットコンテキスト
- オリエンテーション
- 本体
- 1: ねらい: あるワードプロセッサにコピーマルチバッファを実装すること
- 2: テキストフォーマットだけでは充分でない
- 3: 私はwxPythonを使う
- 4: クリップボードデータフォーマット群の若干の基礎
- 5: 'wx.DataObject'の仕様
- 6: 可能なデータフォーマット群をどのようにして先験的に知るか
- 7: 私のコード
- 8: 限界
- 9: テストする
開始コンテキスト
- 読者は、Python プログラミング言語の基本的知識を持っている。
ターゲットコンテキスト
- 読者は、フォーマット毎データの複合体をオペレーティングシステムクリップボードから取得しオペレーティングシステムクリップボードへセットする方法を知る、Pythonにて、wxPythonを用いて。
オリエンテーション
多くの、しかし全てではない、フォーマット群が、本テクニックではサポートされています。
より多くの、しかしそれでも全てではない、フォーマット群が、Microsoft WindowsのためのC#によるあるテクニックによってサポートされています、別シリーズの以降のある記事にて紹介されるとおり。
全てのフォーマットが、LinuxまたはMicrosoft WindowsのためのC++によるあるテクニックによってサポートされています、別シリーズの以降のある記事にて紹介されるとおり。
Python変数はどれもポインターである(必須知識)ことの理由が、ある以前の記事にて説明されています。
本体
1: ねらい: あるワードプロセッサにコピーマルチバッファを実装すること
Hypothesizer 7
私はテキストエディターにVimを使っているが、その恩恵の1つは、コピーマルチバッファが備わっていること: あるテキスト断片をバッファ'a'へコピーし、別のテキスト断片をバッファ'b'へコピーし、などとすることができる。それはとても大きな助けになる。
私はワードプロセッサにLibreOffice Writerを使っているが、そこにもその機能を欲しい。
実のところ、その機能になれているので、それが欠けているのは、少なからぬフラストレーションになる。
Pythonマクロでその機能を実装できる、もしも、それがクリップボードデータを取得およびセットできれば。
2: テキストフォーマットだけでは充分でない
Hypothesizer 7
テキストフォーマットクリップボードデータを取得・セットするのは容易だ。例えば、'pyperclip'がそれを成し遂げられる。
しかし、明らかに、それはワードプロセッサには充分でない: フォント情報がコピーされる必要がある、最低限でも。それに、イメージデータや表のようなオブジェクトも、マルチバッファへコピーされてほしいかもしれない。
理想を言えば、クリップボードデータ全体が、あるがままにコピーされるべきである。
3: 私はwxPythonを使う
Hypothesizer 7
インターネットで探したところ、Pythonでクリップボードデータ全体を取得・設定することのチュートリアルを見つけることはできなかった(テキストデータを操作するものは沢山あるが)。
私はwxPythonを使っているので、それがその機能を持っているかもしれないと期待して、オフィシャルwxPythonドキュメントの中で探してみて、若干の情報を見つけた。
'wx.CustomDataObjec'は有望そうな名前だが、シングルフォーマットのデータのためのものであり、フォーマット毎データの複合体のためのものでないことが判明した。
'wx.DataObjectComposite'は、複合体のためのものだが、かなり扱いにくそうだ、サポートされているデータフォーマット群が事前に確定しているのでなければ。
えーと、'wx.DataObject'(それは、当該ドキュメント中に"for maximum flexibility and efficiency, but it is also the most difficult to implement(最大の柔軟性と効率性があるが、実装するのが最も難しい)"と記述されている)が、私が使うべきもののようだが、それさえも、サポートされているデータフォーマット群が事前に確定していることが前提のようだ(私にはそうではない)。
結局、wxPythonのクリップボード操作のコンセプトは、クリップボードデータ全体を、それがいかなるマルチデータフォーマット群のものであろうとも、取得・セットするという私の関心事にマッチしないが、それで私が何をできるかを見てみよう。
4: クリップボードデータフォーマット群の若干の基礎
Hypothesizer 7
X WindowシステムのクリップボードメカニズムとMicrosoft Windowsのそれとは大いに違っているが、少なくともwxPython的には、各クリップボードデータフォーマットは、常に、そのフォーマットのアイデンティティとして、1つの数字を持っている。
しかし、その数字は、一時的なものであるかもしれない、というのは、あるフォーマットは、ある時は'49161'を持ち、別の時は'49162'を持つということになる。したがって、一般的に言って、恒久的にあるフォーマットをその番号で同定するということはできない('Text'等の一部のおきまりのフォーマットたちは固定された番号を持っているが)。
他方、一部のフォーマットは名前を持っていない(または、少なくとも、それらの名前はAPIで取得できない)。
しかしながら、そうしたフォーマットたちは、固定された番号を持っているはずだ。
したがって、名前を持っているフォーマットたちは名前で同定でき、名前を持っていないフォーマットたちは番号で同定できるということになる。
5: 'wx.DataObject'の仕様
Hypothesizer 7
オフィシャルドキュメントはこのクラスの仕様についてあまり明確でない(特に、各メソッドがいつ呼ばれるかという点について)ので、私は実験をして、必要な情報を知らなければならなかった。
私が発見した重要な1つのポイントは、'wx.DataObject'のインスタンスは、'wx.Clipboard'の'SetData'メソッドに渡された後に無効になるということだ('無効'というのは、'SetData'に再び渡すことはできないということだ)。
えーと、それは、'wx.DataObject'は、私の目的のためにクリップボードデータコンテナとしては使えないということだ(私のクリップボードデータはクリップボードへ繰り返しセットできなければならないから)。したがって、'wx.DataObject'は、クリップボードイベント群ハンドラーだということになる、私にとっては。
以下は、メソッド群がコールされるタイミングについて私が発見したことだ。
| メソッド | いつコールされるか |
|---|---|
| GetFormatCount | 'wx.Clipboard.GetData'がコールされた時 複合体に対して最初に フォーマット毎に最初に 'wx.Clipboard.SetData'がコールされた時 複合体に対して'GetPreferredFormat'の後に フォーマット毎に最初に |
| GetAllFormats | 'wx.Clipboard.GetData'がコールされた時 複合体に対して'GetFormatCount'の後に フォーマット毎に'GetFormatCount'の後に 'wx.Clipboard.SetData'がコールされた時 複合体に対して'GetFormatCount'の後に フォーマット毎に'GetFormatCount'の後に |
| GetDataHere | 'wx.Clipboard.SetData'がコールされた時 フォーマット毎に'GetDataSize'の後に |
| GetDataSize | 'wx.Clipboard.SetData'がコールされた時 フォーマット毎に'GetAllFormats'の後に2度 |
| GetPreferredFormat | 'wx.Clipboard.SetData'がコールされた時 複合体に対して最初に |
| IsSupported | 決して呼ばれない |
| SetData | 'wx.Clipboard.GetData'がコールされた時 フォーマット毎に'GetAllFormats'の後に |
'wx.Clipboard.GetData'のために、'GetFormatCount'および'GetAllFormats'は、先験的に知られた全ての可能なデータフォーマットで返答しなければならない、なぜなら、クリップボード内にどんなデータフォーマット群が存在しているかは私のプログラムには分からないから。しかし、フォーマット毎にコールされるメソッド群は、クリップボード内に存在しているデータフォーマット分のみコールされる('GetAllFormats'にリターンされた全てのフォーマット分ではない)という点は信頼できる。
いずれにせよ、いくつの点が私には謎である。第1に、なぜ、'GetFormatCount'および'GetAllFormats'はフォーマット毎にコールされるのか?第2に、なぜ、'GetDataSize'はフォーマット毎に2度コールされるのか?第3に、'GetPreferredFormat'は、オフィシャルドキュメントに反して'wx.Clipboard.SetData'に対してのみコールされ、それが何をリターンしようが、何の効果も私には見えない。
'GetDataHere'および'SetData'の'buf'引数は、'memoryview'インスタンスである。
6: 可能なデータフォーマット群をどのようにして先験的に知るか
Hypothesizer 7
可能なデータフォーマット群を、どうすれば先験的に知れるだろうか?
Linuxにおいては、以下のコマンドは、クリップボード内に存在するデータフォーマット群を示す。
@bash ソースコード
xclip -t TARGETS -o
Microsoft Windowsにおいては、えーと、あるC++ Win32 APIプログラムを私は作成した、別のシリーズの以降の記事に見られるとおり。
例えば、LibreOffice Writer内のテキスト断片がLinuxにおいてコピーされた時、利用可能なフォーマット群は以下のものだ。
@出力
application/x-openoffice-embed-source-xml;windows_formatname="Star Embed Source (XML)"text/rtftext/richtexttext/htmltext/plain;charset=utf-16application/x-openoffice-objectdescriptor-xml;windows_formatname="Star Object Descriptor (XML)";classname="8BC6B165-B1B2-4EDD-aa47-dae2ee689dd6";typename="LibreOffice 6.4 Text Document";viewaspect="1";width="16999";height="2995";posx="0";posy="0"text/plain;charset=utf-8text/plainUTF8_STRINGSTRINGTEXTTARGETSMULTIPLETIMESTAMPSAVE_TARGETS
Microsoft Windowsでは、利用可能なフォーマット群は以下のものだ。
@出力
DataObjectStar Embed Source (XML)Rich Text FormatRichtext FormatHTML (HyperText Markup Language)HTML FormatUnicodeTextTextLinkStar Object Descriptor (XML)Ole Private DataLocaleOEMText
7: 私のコード
Hypothesizer 7
先程気づいたとおり、'wx.DataObject'は私の目的にはデータコンテナとしては使えない。そこで、私はあるデータコンテナクラス、'theBiasPlanet.coreUtilities.clipboardHandling.ClipboardFormatSpecificDataComposite'(および'theBiasPlanet.coreUtilities.clipboardHandling.ClipboardFormatSpecificDatum'をそのコンポーネントとして)およびあるデータヒストリークラス、'theBiasPlanet.coreUtilities.clipboardHandling.ClipboardFormatSpecificDataCompositesHistory'(それがマルチバッファコンテナである)を作成した。
theBiasPlanet/coreUtilities/clipboardHandling/ClipboardFormatSpecificDatum.py
@Python ソースコード
class ClipboardFormatSpecificDatum:def __init__ (a_this: "ClipboardFormatSpecificDatum", a_formatName: str, a_formatNumber: int, a_datum: bytearray) -> None:a_this.i_formatName: str = a_formatNamea_this.i_formatNumber: int = a_formatNumbera_this.i_datum: bytearray = a_datumdef __del__ (a_this: "ClipboardFormatSpecificDatum") -> None:Nonedef getFormatName (a_this: "ClipboardFormatSpecificDatum") -> str:return a_this.i_formatNamedef getFormatNumber (a_this: "ClipboardFormatSpecificDatum") -> int:return a_this.i_formatNumberdef getDatumSize (a_this: "ClipboardFormatSpecificDatum") -> int:return len (a_this.i_datum)def getDatum (a_this: "ClipboardFormatSpecificDatum") -> bytearray:return a_this.i_datum
theBiasPlanet/coreUtilities/clipboardHandling/ClipboardFormatSpecificDataComposite.py
@Python ソースコード
from typing import Listfrom collections import OrderedDictfrom theBiasPlanet.coreUtilities.clipboardHandling.ClipboardFormatSpecificDatum import ClipboardFormatSpecificDatumclass ClipboardFormatSpecificDataComposite:def __init__ (a_this: "ClipboardFormatSpecificDataComposite") -> None:a_this.i_formatNameToDatumMap: "OrderedDict [str, ClipboardFormatSpecificDatum]" = OrderedDict ()def __del__ (a_this: "ClipboardFormatSpecificDataComposite") -> None:Nonedef addFormatSpecificDatum (a_this: "ClipboardFormatSpecificDataComposite", a_formatSpecificDatum: "ClipboardFormatSpecificDatum") -> bool:a_this.i_formatNameToDatumMap [a_formatSpecificDatum.getFormatName ()] = a_formatSpecificDatumreturn Truedef getFormatNames (a_this: "ClipboardFormatSpecificDataComposite") -> List [str]:l_formatNames: List [str] = []l_formatName: str = Nonefor l_formatName in a_this.i_formatNameToDatumMap:l_formatNames.append (l_formatName)return l_formatNamesdef getFormatSpecificDatum (a_this: "ClipboardFormatSpecificDataComposite", a_formatName: str) -> "ClipboardFormatSpecificDatum":l_formatSpecificDatum: "ClipboardFormatSpecificDatum" = Nonetry:l_formatSpecificDatum = a_this.i_formatNameToDatumMap [a_formatName]except (KeyError) as l_exception:Nonereturn l_formatSpecificDatum
theBiasPlanet/coreUtilities/clipboardHandling/ClipboardFormatSpecificDataCompositesHistory.py
@Python ソースコード
from collections import OrderedDictfrom theBiasPlanet.coreUtilities.clipboardHandling.ClipboardFormatSpecificDataComposite import ClipboardFormatSpecificDataCompositeclass ClipboardFormatSpecificDataCompositesHistory:def __init__ (a_this: "ClipboardFormatSpecificDataCompositesHistory") -> None:a_this.i_dataCompositeKeyToDataCompositeMap: "OrderedDict [str, ClipboardFormatSpecificDataComposite]" = OrderedDict ()def __del__ (a_this: "ClipboardFormatSpecificDataCompositesHistory") -> None:Nonedef addDataComposite (a_this: "ClipboardFormatSpecificDataCompositesHistory", a_dataCompositeKey: str, a_dataComposite: "ClipboardFormatSpecificDataComposite") -> bool:a_this.i_dataCompositeKeyToDataCompositeMap [a_dataCompositeKey] = a_dataCompositereturn Truedef removeDataComposite (a_this: "ClipboardFormatSpecificDataCompositesHistory", a_dataCompositeKey: str) -> bool:try:a_this.i_dataCompositeKeyToDataCompositeMap.pop (a_dataCompositeKey)return Trueexcept (KeyError) as l_exception:return Falsedef getDataComposite (a_this: "ClipboardFormatSpecificDataCompositesHistory", a_dataCompositeKey: str) -> "ClipboardFormatSpecificDataComposite":l_dataComposite: "ClipboardFormatSpecificDataComposite" = Nonetry:l_dataComposite = a_this.i_dataCompositeKeyToDataCompositeMap [a_dataCompositeKey]except (KeyError) as l_exception:Nonereturn l_dataComposite
'wx.DataObject'を拡張したクラスは以下のものだ。
theBiasPlanet/coreUtilities/clipboardHandling/WxPythonClipboardEventsHandler.py
@Python ソースコード
from typing import Listfrom typing import castfrom collections import OrderedDictimport sysfrom wx import DataFormat as wx_DataFormatfrom wx import DataObject as wx_DataObjectimport wxfrom theBiasPlanet.coreUtilities.clipboardHandling.ClipboardFormatSpecificDataComposite import ClipboardFormatSpecificDataCompositefrom theBiasPlanet.coreUtilities.clipboardHandling.ClipboardFormatSpecificDatum import ClipboardFormatSpecificDatumclass WxPythonClipboardEventsHandler (wx_DataObject):s_possibleDatumFormatNameToFormatMap: "OrderedDict [str, wx_DataFormat]" = Nones_preferedDatumFormatName: str = Nones_possibleDatumFormats: List [wx_DataFormat] = None@staticmethoddef getDatumFormatName (a_datumFormat: wx_DataFormat) -> str:l_datumFormatNumber: int = a_datumFormat.GetType ()l_datumFormatName: str = Noneif l_datumFormatNumber == wx.DF_TEXT:l_datumFormatName = "Text"elif l_datumFormatNumber == wx.DF_BITMAP:l_datumFormatName = "Bitmap"elif l_datumFormatNumber == wx.DF_METAFILE:l_datumFormatName = "Metafile"elif l_datumFormatNumber == wx.DF_FILENAME:l_datumFormatName = "Filename"elif l_datumFormatNumber == wx.DF_HTML:l_datumFormatName = "HTML Format"else:l_datumFormatName = a_datumFormat.GetId ()return l_datumFormatNamedef __init__ (a_this: "WxPythonClipboardEventsHandler", a_formatSpecificDataComposite: "ClipboardFormatSpecificDataComposite") -> None:a_this.i_formatSpecificDataComposite: "ClipboardFormatSpecificDataComposite" = a_formatSpecificDataCompositea_this.i_supportedDatumFormats: List [wx_DataFormat] = Nonesuper ().__init__ ()l_availableDatumFormatNames: List [str] = a_this.i_formatSpecificDataComposite.getFormatNames ()if len (l_availableDatumFormatNames) > 0:a_this.i_supportedDatumFormats = []l_datumFormatName: str = Nonefor l_datumFormatName in l_availableDatumFormatNames:a_this.i_supportedDatumFormats.append (WxPythonClipboardEventsHandler.s_possibleDatumFormatNameToFormatMap [l_datumFormatName])else:a_this.i_supportedDatumFormats = WxPythonClipboardEventsHandler.s_possibleDatumFormatsdef getFormatSpecificDataComposite (a_this: "WxPythonClipboardEventsHandler") -> "ClipboardFormatSpecificDataComposite":return a_this.i_formatSpecificDataCompositedef GetFormatCount (a_this: "WxPythonClipboardEventsHandler", a_datumTransferDirection: wx_DataObject.Direction = wx_DataObject.Direction.Get) -> int:sys.stdout.write ("### GetFormatCount: {0:d}\n".format (len (a_this.i_supportedDatumFormats)))return len (a_this.i_supportedDatumFormats)def GetAllFormats (a_this: "WxPythonClipboardEventsHandler", a_datumTransferDirection: wx_DataObject.Direction = wx_DataObject.Direction.Get) -> List [wx_DataFormat]:sys.stdout.write ("### GetAllFormats:\n")return a_this.i_supportedDatumFormats# 'a_formatSpecificDatum' is not really 'bytearray', but 'memoryview', but the stub of 'memoryview' seems to be mistaken, which makes me use 'bytearray' instead.def GetDataHere (a_this: "WxPythonClipboardEventsHandler", a_datumFormat: wx_DataFormat, a_formatSpecificDatum: bytearray) -> bool:sys.stdout.write ("### GetDataHere: {0:s}\n".format (WxPythonClipboardEventsHandler.getDatumFormatName (a_datumFormat)))l_formatSpecificDatumIsFound: bool = Falseif a_formatSpecificDatum is not None:l_formatSpecificDatum: "ClipboardFormatSpecificDatum" = a_this.i_formatSpecificDataComposite.getFormatSpecificDatum (WxPythonClipboardEventsHandler.getDatumFormatName (a_datumFormat))if l_formatSpecificDatum is not None:l_copiedFormatSpecificDatum: bytearray = l_formatSpecificDatum.getDatum ()l_byteIndex: int = 0for l_byteIndex in range (0, len (a_formatSpecificDatum), 1):#a_formatSpecificDatum [l_byteIndex:l_byteIndex + 1] = cast (Sequence [bytes], bytes ([l_copiedFormatSpecificDatum [l_byteIndex]])) # This is if I rather use 'memoryview'.a_formatSpecificDatum [l_byteIndex] = l_copiedFormatSpecificDatum [l_byteIndex]l_formatSpecificDatumIsFound = Truereturn l_formatSpecificDatumIsFounddef GetDataSize (a_this: "WxPythonClipboardEventsHandler", a_datumFormat: wx_DataFormat) -> int:sys.stdout.write ("### GetDataSize:\n")l_size: int = 0l_formatSpecificDatum: "ClipboardFormatSpecificDatum" = a_this.i_formatSpecificDataComposite.getFormatSpecificDatum (WxPythonClipboardEventsHandler.getDatumFormatName (a_datumFormat))if l_formatSpecificDatum is not None:l_size = len (l_formatSpecificDatum.getDatum ())return l_sizedef GetPreferredFormat (a_this: "WxPythonClipboardEventsHandler", a_datumTransferDirection: wx_DataObject.Direction = wx_DataObject.Direction.Get) -> wx_DataFormat:sys.stdout.write ("### GetPreferredFormat:\n")return WxPythonClipboardEventsHandler.s_possibleDatumFormatNameToFormatMap [WxPythonClipboardEventsHandler.s_preferedDatumFormatName]def IsSupported (a_this: "WxPythonClipboardEventsHandler", a_datumFormat: wx_DataFormat, a_datumTransferDirection: wx_DataObject.Direction = wx_DataObject.Direction.Get) -> bool:sys.stdout.write ("### IsSupported:\n")try:WxPythonClipboardEventsHandler.s_possibleDatumFormatNameToFormatMap [WxPythonClipboardEventsHandler.getDatumFormatName (a_datumFormat)]return Trueexcept (KeyError) as l_exception:return Falsedef SetData (a_this: "WxPythonClipboardEventsHandler", a_datumFormat: wx_DataFormat, a_formatSpecificDatum: memoryview) -> bool:sys.stdout.write ("### SetData: {0:s}\n".format (WxPythonClipboardEventsHandler.getDatumFormatName (a_datumFormat)))l_datumFormatName: str = WxPythonClipboardEventsHandler.getDatumFormatName (a_datumFormat)if a_formatSpecificDatum is not None:l_datumSize = len (a_formatSpecificDatum)l_copiedFormatSpecificDatum: bytearray = Noneif l_datumFormatName == "Text" or l_datumFormatName == "HTML Format":l_copiedFormatSpecificDatum = bytearray (l_datumSize + 1)l_copiedFormatSpecificDatum [l_datumSize] = 0else:l_copiedFormatSpecificDatum = bytearray (l_datumSize)l_byteIndex: int = 0for l_byteIndex in range (0, len (a_formatSpecificDatum), 1):l_copiedFormatSpecificDatum [l_byteIndex] = a_formatSpecificDatum [l_byteIndex]a_this.i_formatSpecificDataComposite.addFormatSpecificDatum (ClipboardFormatSpecificDatum (l_datumFormatName, a_datumFormat.GetType (), l_copiedFormatSpecificDatum))return False
勿論、'GetDataHere'で、'a_formatSpecificDatum = l_formatSpecificDatum.getDatum ()'のようにはできない(もしも、できると思われるのであれば、Python変数というものはポインターであることを理解されていない)。
クリップボード操作クラスは以下のものだ。
theBiasPlanet/coreUtilities/clipboardHandling/WxPythonClipboard.py
@Python ソースコード
from typing import Listfrom collections import OrderedDictfrom wx import DataFormat as wx_DataFormatimport wxfrom theBiasPlanet.coreUtilities.clipboardHandling.ClipboardFormatSpecificDataComposite import ClipboardFormatSpecificDataCompositefrom theBiasPlanet.coreUtilities.clipboardHandling.WxPythonClipboardEventsHandler import WxPythonClipboardEventsHandlerclass WxPythonClipboard:@staticmethoddef setUp (a_datumFormatNameToFormatMap: "OrderedDict [str, wx_DataFormat]", a_preferedDatumFormatName: str) -> bool:WxPythonClipboardEventsHandler.s_possibleDatumFormatNameToFormatMap = a_datumFormatNameToFormatMapWxPythonClipboardEventsHandler.s_preferedDatumFormatName = a_preferedDatumFormatNameWxPythonClipboardEventsHandler.s_possibleDatumFormats = []l_datumFormatName: str = Nonefor l_datumFormatName in WxPythonClipboardEventsHandler.s_possibleDatumFormatNameToFormatMap:WxPythonClipboardEventsHandler.s_possibleDatumFormats.append (WxPythonClipboardEventsHandler.s_possibleDatumFormatNameToFormatMap [l_datumFormatName])return True@staticmethoddef openClipboard () -> bool:wx.TheClipboard.Open ()return True@staticmethoddef closeClipboard () -> bool:wx.TheClipboard.Close ()return True@staticmethoddef clearClipboard () -> bool:wx.TheClipboard.Clear ()return True@staticmethoddef getFormatSpecificDataComposite () -> "ClipboardFormatSpecificDataComposite":l_wxPythonClipboardEventsHandler: "WxPythonClipboardEventsHandler" = WxPythonClipboardEventsHandler (ClipboardFormatSpecificDataComposite ())wx.TheClipboard.GetData (l_wxPythonClipboardEventsHandler)return l_wxPythonClipboardEventsHandler.getFormatSpecificDataComposite ()@staticmethoddef setFormatSpecificDataComposite (a_formatSpecificDataComposite: "ClipboardFormatSpecificDataComposite") -> bool:l_wxPythonClipboardEventsHandler: "WxPythonClipboardEventsHandler" = WxPythonClipboardEventsHandler (a_formatSpecificDataComposite)wx.TheClipboard.SetData (l_wxPythonClipboardEventsHandler)wx.TheClipboard.Flush ()return True
8: 限界
Hypothesizer 7
実のところ、全てのフォーマットのデータが、このテクニックで取得・セットできるわけではない。
例えば、Microsoft Windowsでは、LibreOffice Writerクリップボードデータについて、'UnicodeText'、'Locale'、'OEMText'データは取得できない。
なぜか?えーと、Microsoft Windowsでは、任意のフォーマットのデータが1つの共通の方法で単純にバイト配列として取得できるというわけではなく、あるフォーマットのデータは、ある特定の方法で取得しなければならないのだが、wxPythonは、全ての可能なフォーマットをサポートする努力をしなかったということだ。
サポートされているフォーマット群が満足いくものでないのであれば、別のテクニックへ向かわなければならない(C#用の記事およびC++用の記事があります)だろう。
9: テストする
Hypothesizer 7
私のMicrosoft Windows用のテストコードは以下のものだ。
@Python ソースコード
from typing import Listrom typing import TextIOimport sysimport wxfrom theBiasPlanet.coreUtilities.clipboardHandling.ClipboardFormatSpecificDataComposite import ClipboardFormatSpecificDataCompositefrom theBiasPlanet.coreUtilities.clipboardHandling.ClipboardFormatSpecificDataCompositesHistory import ClipboardFormatSpecificDataCompositesHistoryfrom theBiasPlanet.coreUtilities.clipboardHandling.ClipboardFormatSpecificDatum import ClipboardFormatSpecificDatumfrom theBiasPlanet.coreUtilities.clipboardHandling.WxPythonClipboard import WxPythonClipboardfrom theBiasPlanet.coreUtilities.clipboardHandling.WxPythonClipboardEventsHandler import WxPythonClipboardEventsHandlerfrom theBiasPlanet.coreUtilities.constantsGroups.ClipboardDatumFormatNameToFormatMapsConstantsGroup import ClipboardDatumFormatNameToFormatMapsConstantsGroupclass Test1Test:@staticmethoddef main (a_arguments: List [str]) -> None:Test1Test.test ()@staticmethoddef test () -> None:l_clipbardFormatSpecificDataCompositesHistory: "ClipboardFormatSpecificDataCompositesHistory" = ClipboardFormatSpecificDataCompositesHistory ()l_standardInputReader: TextIO = sys.stdinWxPythonClipboard.setUp (ClipboardDatumFormatNameToFormatMapsConstantsGroup.c_windowsDatumFormatNameToFormatMap, "Text")while True:sys.stdout.write ("### Input 'S' (Set), 'G' (Get), 'D (Display)', or 'Q' (Quit):\n")sys.stdout.flush ()l_userInput: str = l_standardInputReader.read (2)l_clipboardFormatSpecificDataCompositeKey: strif l_userInput.startswith ("S") or l_userInput.startswith ("G") or l_userInput.startswith ("D"):sys.stdout.write ("### Input the key:\n")sys.stdout.flush ()l_clipboardFormatSpecificDataCompositeKey = l_standardInputReader.read (2) [0]if l_userInput.startswith ("S"):WxPythonClipboard.openClipboard ()WxPythonClipboard.clearClipboard ()WxPythonClipboard.setFormatSpecificDataComposite (l_clipbardFormatSpecificDataCompositesHistory.getDataComposite (l_clipboardFormatSpecificDataCompositeKey))WxPythonClipboard.closeClipboard ()elif l_userInput.startswith ("G"):WxPythonClipboard.openClipboard ()l_clipbardFormatSpecificDataCompositesHistory.addDataComposite (l_clipboardFormatSpecificDataCompositeKey, WxPythonClipboard.getFormatSpecificDataComposite ())WxPythonClipboard.closeClipboard ()elif l_userInput.startswith ("D"):l_clipboardFormatSpecificDataComposite: "ClipboardFormatSpecificDataComposite " = l_clipbardFormatSpecificDataCompositesHistory.getDataComposite (l_clipboardFormatSpecificDataCompositeKey)l_clipboardDatumFormatNames: List [str] = l_clipboardFormatSpecificDataComposite.getFormatNames ()l_clipboardDatumFormatName: str = Nonefor l_clipboardDatumFormatName in l_clipboardDatumFormatNames:l_clipboardFormatSpecificDatum: "ClipboardFormatSpecificDatum " = l_clipboardFormatSpecificDataComposite.getFormatSpecificDatum (l_clipboardDatumFormatName)sys.stdout.write ("### clipboard datum format number, format name, size: {0:d}, {1:s}, {2:d}\n".format (l_clipboardFormatSpecificDatum.getFormatNumber (), l_clipboardDatumFormatName, l_clipboardFormatSpecificDatum.getDatumSize ()))sys.stdout.flush ()else:breakif __name__ == "__main__":l_application = wx.App ()Test1Test.main (sys.argv)
theBiasPlanet/coreUtilities/constantsGroups/ClipboardDatumFormatNameToFormatMapsConstantsGroup.py
@Python ソースコード
from collections import OrderedDictfrom wx import DataFormat as wx_DataFormatimport wxclass ClipboardDatumFormatNameToFormatMapsConstantsGroup:c_linuxDatumFormatNameToFormatMap: "OrderedDict [str, wx_DataFormat]" = OrderedDict ({"Text": wx_DataFormat (wx.DF_TEXT), "Bitmap": wx_DataFormat (wx.DF_BITMAP), "Metafile": wx_DataFormat (wx.DF_METAFILE), "Filename": wx_DataFormat (wx.DF_FILENAME), "HTML Format": wx_DataFormat (wx.DF_HTML), "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"": wx_DataFormat ("application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\""), "text/rtf": wx_DataFormat ("text/rtf"), "text/richtext": wx_DataFormat ("text/richtext"), "text/html": wx_DataFormat ("text/html"), "text/plain;charset=utf-16": wx_DataFormat ("text/plain;charset=utf-16"), "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\";classname=\"8BC6B165-B1B2-4EDD-aa47-dae2ee689dd6\";typename=\"LibreOffice 6.4 Text Document\";viewaspect=\"1\";width=\"16999\";height=\"2995\";posx=\"0\";posy=\"0\"": wx_DataFormat ("application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\";classname=\"8BC6B165-B1B2-4EDD-aa47-dae2ee689dd6\";typename=\"LibreOffice 6.4 Text Document\";viewaspect=\"1\";width=\"16999\";height=\"2995\";posx=\"0\";posy=\"0\""), "text/plain;charset=utf-8": wx_DataFormat ("text/plain;charset=utf-8"), "text/plain": wx_DataFormat ("text/plain"), "UTF8_STRING": wx_DataFormat ("UTF8_STRING"), "STRING": wx_DataFormat ("STRING"), "TEXT": wx_DataFormat ("TEXT"), "MULTIPLE": wx_DataFormat ("MULTIPLE"), "TIMESTAMP": wx_DataFormat ("TIMESTAMP")})c_windowsDatumFormatNameToFormatMap: "OrderedDict [str, wx_DataFormat]" = OrderedDict ({"Text": wx_DataFormat (wx.DF_TEXT), "Metafile": wx_DataFormat (wx.DF_METAFILE), "Filename": wx_DataFormat (wx.DF_FILENAME), "UnicodeText": wx_DataFormat ("UnicodeText"), "Locale": wx_DataFormat ("Locale"), "OEMText": wx_DataFormat ("OEMText"), "DataObject": wx_DataFormat ("DataObject"), "Preferred DropEffect": wx_DataFormat ("Preferred DropEffect"), "Ole Private Data": wx_DataFormat ("Ole Private Data"), "HTML Format": wx_DataFormat (wx.DF_HTML), "HTML (HyperText Markup Language)": wx_DataFormat ("HTML (HyperText Markup Language)"), "Star Embed Source (XML)": wx_DataFormat ("Star Embed Source (XML)"), "Rich Text Format": wx_DataFormat ("Rich Text Format"), "Richtext Format": wx_DataFormat ("Richtext Format"), "Link": wx_DataFormat ("Link"), "Star Object Descriptor (XML)": wx_DataFormat ("Star Object Descriptor (XML)"), "GDIMetaFile": wx_DataFormat ("GDIMetaFile"), "EnhancedMetafile": wx_DataFormat ("EnhancedMetafile"), "MetaFilePict": wx_DataFormat ("MetaFilePict"), "PNG": wx_DataFormat ("PNG"), "DeviceIndependentBitmap": wx_DataFormat ("DeviceIndependentBitmap"), "Windows Bitmap": wx_DataFormat ("Windows Bitmap"), "SymbolicLink": wx_DataFormat ("SymbolicLink"), "DataInterchangeFormat": wx_DataFormat ("DataInterchangeFormat"), "EditEngine ODF": wx_DataFormat ("EditEngine ODF")})
'cmd'ターミナル上であるテキスト断片をコピーした後、'G' -> 'A' -> 'D' -> 'A'というインプットに対して、以下のようなアウトプットを得る。
@出力
### clipboard datum format number, format name, size: 1, Text, 8
LibreOffice Writerインスタンス上であるテキスト断片をコピーした後、'G' -> 'A' -> 'D' -> 'A'というインプットに対して、以下のようなアウトプットを得る。
@出力
### clipboard datum format number, format name, size: 1, Text, 37### clipboard datum format number, format name, size: 49161, DataObject, 8### clipboard datum format number, format name, size: 49171, Ole Private Data, 552### clipboard datum format number, format name, size: 30, HTML Format, 772### clipboard datum format number, format name, size: 49819, HTML (HyperText Markup Language), 667### clipboard datum format number, format name, size: 49817, Star Embed Source (XML), 6279### clipboard datum format number, format name, size: 49285, Rich Text Format, 2675### clipboard datum format number, format name, size: 49790, Richtext Format, 2675### clipboard datum format number, format name, size: 49852, Link, 111### clipboard datum format number, format name, size: 49853, Star Object Descriptor (XML), 164
Linux用には、予期されるクリップボードデータフォーマット群を変更しなければならない。