Pythonでクリップボードとのデータのやりとりをする

Pythonでクリップボードへコピー、およびクリップボードからのペーストをしてみます。

目次

  1. tkinterでクリップボードにアクセスする
  2. tkinterでCrtl+CとCtrl+Vを有効にする
  3. tkinterでのコピーとペーストを試してみた

tkinterでクリップボードにアクセスする

tkinterモジュールを使ったGUIを作っていて、クリップボードへ出し入れするデータが文字列の場合なら、tkinterのクリップボードへのアクセス機能を使うのが便利です。

クリップボードから画像を読み込む場合は、 Pillow(PIL)を使う方法 があります。また、クリップボードに画像をコピーする場合は、 Pywin32を使う方法 があります。

tkinterにはクリップボードへアクセスするメソッドがあります。クリップボードとやりとりできるデータは、既定値では文字列です。

clipboard_get()
clipboard_append()
clipboard_clear()

clipboard_get()はクリップボードからペーストするメソッド、clipboard_append()はクリップボードにコピーするメソッドです。clipboard_clear()はクリップボードを空にするメソッドなのですが、当方の環境(Windows10)では動作しませんでした。

クリップボードに画像が入っているときにclipboard_get()メソッドを使うとエラーになるので注意です。また、clipboard_get()メソッドの戻り値は、数字であっても文字列になります。

tkinterでCrtl+CとCtrl+Vを有効にする

Windowsの標準的なショートカット「Ctrl+C」と「Ctrl+V」をコピーとペーストに割り当てるには、tkinterのbindメソッドを使用します。

bind(self, sequence, func, [add])
変数 内容
sequence str イベントを表す文字列
func object イベントが起きたときに呼び出される関数
add str 省略可。既定値は空文字列。空文字列の場合はバインドの置き換え。+にすると追加。

tkinterのウィジェットでbindメソッドを実行することで、指定したイベントが発生するのを待機して、イベントが発生したら指定の関数を呼び出すことができるようになります。

ウィンドウウィジェットに特定のキー入力のイベントをbindしておいてclipboard_get()メソッドやclipboard_append()メソッドを呼び出すようにしておくことで、ショートカットキーによるコピーとペーストを実現します。

tkinterでのコピーとペーストを試してみた

サンプルコードです。実行するとボタンとテキストボックスが並んだアプリが起動します。

import tkinter as tk
import sys

class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.create_widgets()

    def create_widgets(self):
        self.frame = tk.Frame(self.master)
        self.frame.pack()

        self.button_get = tk.Button(self.frame, text='Paste', command=self.get_data)
        self.button_get.pack()
        self.button_append = tk.Button(self.frame, text='Append', command=self.set_data)
        self.button_append.pack()

        self.v = tk.StringVar()
        self.textbox = tk.Entry(self.master, textvariable=self.v)
        self.textbox.pack()

        self.master.bind('<Control-v>', self.get_data)
        self.master.bind('<Control-V>', self.get_data)
        self.master.bind('<Control-c>', self.set_data)
        self.master.bind('<Control-C>', self.set_data)


    def get_data(self, event=None):
        try:
            input_string = self.clipboard_get()
            self.v.set(input_string)
        except:
            print(sys.exc_info()[1])

    def set_data(self, event=None):
        output_string = self.v.get()
        self.clipboard_append(output_string)

root = tk.Tk()
app = Application(master=root)
app.mainloop()

GUIの画面を定義する部分があるので少し長いですが、流れとしては単純です。

tk.Button()の引数のcommandに、そのボタンがクリックされたときに実行される関数を指定します。また、bind()メソッドでショートカットキーと実行する関数の関係を指定しています。

tk.Button()からcommandの指定で呼び出す際には引数は1つなのですが、bind()で呼び出す際にはeventという引数が追加されます。そこで、これらのメソッドが呼び出す関数にはevent=Noneのように2つ目の引数を定義して既定値を設定することで、呼び出されたときの引数の変化に対応しています。

clipboard_get()メソッドのところでtry句を使用しているのは、クリップボードに入っているデータが文字列でない場合のときの対処です。except句でエラーメッセージを表示しているのでこのコードではあまり意味がありませんが、実際に使用するときにはexceptにいろいろ処理を書くことになると思います。

実行するとこうなります。

tkinter実行画面

広告

PythonでGUIカテゴリの投稿