WindowsのPythonでクリップボードを扱う
WindowsのPythonでwin32clipboardモジュールを使ってクリップボードを扱う方法を説明しています。
win32clipboard以外にもクリップボードを扱うモジュールはありますが、JupyterLabではwin32clipboardは最初から含まれているので別途インストールする必要がありません。
JupyterLabを使わない場合でも、pipでpywin32パッケージをインストールすれば同じように使えます。
JupyterLab(ジュパイター・ラボ/ジュピター・ラボ)は、データ分析などで広く使われているJupyter notebook後継のWebブラウザ上で動くPythonの実行環境です。
プログラムを書いて実行することができます。実行結果も含めることが出来ます。さらにMarkdownを使って表現力豊かなテキストや図表も同時に書くことができます。そして、その結果をHTMLやPDFで出力することができます。
Jupyter notebook/JupyterLabは、Python以外にも多くの言語サポートしています。
Jupyterの読み方は「ジュパイター・ラボ」と「ジュピター・ラボ」の2種類があるようです。どちらが正しいかは色々な意見があるようです。興味がある方は「jupyter ジュパイター ジュピター」で検索してみてください。
インストール
win32clipboardはpywin32パッケージに含まれています。JupyterLabでは標準でpywin32パッケージがインストールされているのでインストールする必要はありません。
pywin32がインストールされていない場合はpipなどでpywin32パッケージをインストールしてください。
文字列用クリップボード関数
以下は文字列をクリップボードに設定する関数と、クリップボードから取得する関数です。
使い方は下の通りです。
設定する文字列を引数にしてset_clipboard_text関数を呼び出すとクリップボードに文字列を設定することができます。
get_clipboard_text関数を呼び出すとクリップボードの値が取得できます。
get_clipboard_text関数は、クリップボードに文字列が無いときはNoneを返すようになっています。
解説
win32clipboardモジュールの関数は、ほぼWindowsのクリップボード関連の関数と対応しています。(完全に対応しているわけではありませんが、ほとんど対応しています)
Windowsのクリップボード関連の関数では、クリップボードに設定するデータのためにグローバルメモリオブジェクトを割り当てるなどの処理が必要ですが、グローバルメモリオブジェクトの割り当てなどは、win32clipboardモジュールの中で行っているため気にする必要はありません。
クリップボードを使うときは、OpenClipboard関数でオープンして使い終わったらCloseClipboard関数でクローズします。
OpenClipboard関数を呼び出したあとCloseClipboard関数を呼ぶまで他のアプリケーションがクリップボードを使えません。このため、できるだけOpenClipboard関数 ~ CloseClipboard関数を呼ぶまでの間隔は短くする必要があります。クリップボードに設定するデータを準備するのに時間がかかる場合は、OpenClipboard関数を呼ぶ前にデータを準備してからOpenClipboard関数を呼び出すようにします。
OpenClipboard関数でオープンした後は、必ずCloseClipboard関数を呼ぶ必要があります。
以下の解説用のコードでは、シンプルにするためにエラー処理を行っていませんが、実装する場合はfinallyを使ってCloseClipboard関数を呼ぶようにしてください。
クリップボードの扱い方の基本
クリップボードに文字列を設定する
クリップボードに値を設定するときEmptyClipboard関数を呼び出さなくて正しく動く場合がありますが、クリップボードに予期しないデータが残っていたり、正しく動作しなくなったりする場合があるので特別な理由がなければ呼び出すようにします。
CF_TEXTは、ASCIIキャラク用のため漢字も使う場合はCF_UNICODETEXTを使う必要があります。また、Pythonの文字列がUNICODEなのでCF_TEXTでは正しく設定できません。
CF_TEXTを使う場合は文字列ではなく、バイト配列に変換する必要があります。
クリップボードから文字列を取得する
クリップボードの値を取得するときは、取得するデータ形式を引数としてGetClipboardData関数を呼び出します。テキストを取得する場合は、CF_UNICODETEXTを指定します。
クリップボードに指定したデータ形式のデータがない場合は例外(TypeError)が発生します。
複数のデータ形式を扱う
以下のコードで、複数のデータ形式をクリップボードに設定したり取得したりできます。
クリップボードに複数のデータ形式の文字列を設定する
複数のデータ形式を設定する場合は、EmptyClipboard関数を呼び出してクリップボードを空にした後に、設定したいデータ形式とデータを引数としてSetClipboardData関数を複数回呼び出します。
クリップボードから複数のデータ形式を取得する
クリップボードのデータをGetClipboardData関数で取得するためには、引数に取得したいデータ形式を指定する必要があります。このため、最初に現在クリップボードにあるデータ形式を取得する必要があります。
現在クリップボードにあるすべてのデータ形式のデータを取得するには、最初にCountClipboardFormats関数で現在クリップボードにあるデータ形式の数を取得します。
次に、取得したデータ形式の数だけEnumClipboardFormats関数を呼び出してデータ形式を取得し、取得したデータ形式を使ってGetClipboardData関数を呼び出します。
あらかじめ期待するデータ形式がわかっている場合は、CountClipboardFormats関数やEnumClipboardFormats関数で現在クリップボードにあるデータ形式を取得しないで、直接GetClipboardData関数を期待するデータ形式を引数として呼び出すこともできます。
この場合は、期待するデータ形式がクリップボードにないと例外(TypeError)が発生するので例外を処理するようにしてください。
win32clipboardで定義されているCF_xxxの一覧は以下のコマンドで見ることができます。
CF_TEXTやCF_UNICODEなどのCF_xxxは、win32clipboardに定義されていますが、win32conにも定義されています。どちらを使うことも出来ます。