ユーザー入力から文字列を構築し、クリップボードに追加する基本的なWindowsアプリケーションを作成しようとしています。 Pythonを使用して文字列をクリップボードにコピーするにはどうすればよいですか?
実際、pywin32
とctypes
は、この単純なタスクには過剰すぎるようです。 Tkinter
はクロスプラットフォームGUIフレームワークであり、デフォルトでPythonとともに出荷され、他のクールなものと一緒にメソッドにアクセスするクリップボードがあります。
必要なのがテキストをシステムのクリップボードに入れることだけである場合、これはそれを行います:
from Tkinter import Tk
r = Tk()
r.withdraw()
r.clipboard_clear()
r.clipboard_append('i can has clipboardz?')
r.update() # now it stays on the clipboard after the window is closed
r.destroy()
それだけです。プラットフォーム固有のサードパーティライブラリをいじる必要はありません。
Python 3を使用している場合は、TKinter
をtkinter
に置き換えます。
解決策はありませんでしたが、回避策がありました。
Windows Vista以降には、clip
と呼ばれる組み込みコマンドがあり、コマンドラインからコマンドの出力を取得してクリップボードに入れます。たとえば、ipconfig | clip
。
そこで、組み込みのWindowsソリューションを使用して、文字列を取得してクリップボードに追加するos
モジュールを使用して関数を作成しました。
import os
def addToClipBoard(text):
command = 'echo ' + text.strip() + '| clip'
os.system(command)
# Example
addToClipBoard('penny lane')
# Penny Lane is now in your ears, eyes, and clipboard.
ただし、前述のコメントで述べたように、このアプローチの欠点の1つは、echo
コマンドがテキストの末尾に改行を自動的に追加することです。これを回避するには、コマンドの修正バージョンを使用できます。
def addToClipBoard(text):
command = 'echo | set /p nul=' + text.strip() + '| clip'
os.system(command)
Windows XPを使用している場合は、Windowsからコピーして貼り付けるXP Proのコマンドプロンプトをクリップボードに直接入力する。
Ctypesを使用してWindows APIを利用し、大規模なpywin32パッケージを回避することもできます。これは私が使用するものです(スタイルが悪いのは許しますが、アイデアはそこにあります):
import ctypes
# Get required functions, strcpy..
strcpy = ctypes.cdll.msvcrt.strcpy
ocb = ctypes.windll.user32.OpenClipboard # Basic clipboard functions
ecb = ctypes.windll.user32.EmptyClipboard
gcd = ctypes.windll.user32.GetClipboardData
scd = ctypes.windll.user32.SetClipboardData
ccb = ctypes.windll.user32.CloseClipboard
ga = ctypes.windll.kernel32.GlobalAlloc # Global memory allocation
gl = ctypes.windll.kernel32.GlobalLock # Global memory Locking
gul = ctypes.windll.kernel32.GlobalUnlock
GMEM_DDESHARE = 0x2000
def Get():
ocb(None) # Open Clip, Default task
pcontents = gcd(1) # 1 means CF_TEXT.. too lazy to get the token thingy...
data = ctypes.c_char_p(pcontents).value
#gul(pcontents) ?
ccb()
return data
def Paste(data):
ocb(None) # Open Clip, Default task
ecb()
hCd = ga(GMEM_DDESHARE, len(bytes(data,"ascii")) + 1)
pchData = gl(hCd)
strcpy(ctypes.c_char_p(pchData), bytes(data, "ascii"))
gul(hCd)
scd(1, hCd)
ccb()
組み込みのクリップボードサポートを備えた優れたパンダを使用できますが、DataFrameを渡す必要があります。
import pandas as pd
df=pd.DataFrame(['Text to copy'])
df.to_clipboard(index=False,header=False)
なんらかの理由で、私はTkソリューションを私のために機能させることができませんでした。 kapaceのソリューション ははるかに実行可能ですが、書式設定は私のスタイルに反しており、Unicodeでは機能しません。これが変更されたバージョンです。
import ctypes
OpenClipboard = ctypes.windll.user32.OpenClipboard
EmptyClipboard = ctypes.windll.user32.EmptyClipboard
GetClipboardData = ctypes.windll.user32.GetClipboardData
SetClipboardData = ctypes.windll.user32.SetClipboardData
CloseClipboard = ctypes.windll.user32.CloseClipboard
CF_UNICODETEXT = 13
GlobalAlloc = ctypes.windll.kernel32.GlobalAlloc
GlobalLock = ctypes.windll.kernel32.GlobalLock
GlobalUnlock = ctypes.windll.kernel32.GlobalUnlock
GlobalSize = ctypes.windll.kernel32.GlobalSize
GMEM_MOVEABLE = 0x0002
GMEM_ZEROINIT = 0x0040
unicode_type = type(u'')
def get():
text = None
OpenClipboard(None)
handle = GetClipboardData(CF_UNICODETEXT)
pcontents = GlobalLock(handle)
size = GlobalSize(handle)
if pcontents and size:
raw_data = ctypes.create_string_buffer(size)
ctypes.memmove(raw_data, pcontents, size)
text = raw_data.raw.decode('utf-16le').rstrip(u'\0')
GlobalUnlock(handle)
CloseClipboard()
return text
def put(s):
if not isinstance(s, unicode_type):
s = s.decode('mbcs')
data = s.encode('utf-16le')
OpenClipboard(None)
EmptyClipboard()
handle = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, len(data) + 2)
pcontents = GlobalLock(handle)
ctypes.memmove(pcontents, data, len(data))
GlobalUnlock(handle)
SetClipboardData(CF_UNICODETEXT, handle)
CloseClipboard()
paste = get
copy = put
この答えは、拡張Unicode文字とPython 3によりよく対処するために最初に作成されてから変更されています。Python 2.7と3.5の両方でテストされ、絵文字でも動作します\U0001f601 (????)
など。
サイトパッケージにwin32clipboardを追加する必要があるようです。 pywin32パッケージ の一部です
最も簡単な方法は pyperclip を使用することです。 python 2および3で動作します。
このライブラリをインストールするには、次を使用します。
pip install pyperclip
使用例:
import pyperclip
pyperclip.copy("your string")
クリップボードの内容を取得する場合:
clipboard_content = pyperclip.paste()
さまざまな解決策を試しましたが、これは my test に合格する最も簡単な解決策です:
#coding=utf-8
import win32clipboard # http://sourceforge.net/projects/pywin32/
def copy(text):
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(text, win32clipboard.CF_UNICODETEXT)
win32clipboard.CloseClipboard()
def paste():
win32clipboard.OpenClipboard()
data = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT)
win32clipboard.CloseClipboard()
return data
if __== "__main__":
text = "Testing\nthe “clip—board”: ????"
try: text = text.decode('utf8') # Python 2 needs decode to make a Unicode string.
except AttributeError: pass
print("%r" % text.encode('utf8'))
copy(text)
data = paste()
print("%r" % data.encode('utf8'))
print("OK" if text == data else "FAIL")
try: print(data)
except UnicodeEncodeError as er:
print(er)
print(data.encode('utf8'))
Windows 8.1のPython 3.4およびWindows 7のPython 2.7でOKをテストしました。また、WindowsからコピーされたUnixラインフィードでUnicodeデータを読み取る場合。 Pythonが終了した後、コピーされたデータはクリップボードに残ります:"Testing the “clip—board”: ????"
外部の依存関係が不要な場合は、次のコードを使用します(クロスプラットフォームpyperclip
-C:\Python34\Scripts\pip install --upgrade pyperclip
の一部になりました)。
def copy(text):
GMEM_DDESHARE = 0x2000
CF_UNICODETEXT = 13
d = ctypes.windll # cdll expects 4 more bytes in user32.OpenClipboard(None)
try: # Python 2
if not isinstance(text, unicode):
text = text.decode('mbcs')
except NameError:
if not isinstance(text, str):
text = text.decode('mbcs')
d.user32.OpenClipboard(0)
d.user32.EmptyClipboard()
hCd = d.kernel32.GlobalAlloc(GMEM_DDESHARE, len(text.encode('utf-16-le')) + 2)
pchData = d.kernel32.GlobalLock(hCd)
ctypes.cdll.msvcrt.wcscpy(ctypes.c_wchar_p(pchData), text)
d.kernel32.GlobalUnlock(hCd)
d.user32.SetClipboardData(CF_UNICODETEXT, hCd)
d.user32.CloseClipboard()
def paste():
CF_UNICODETEXT = 13
d = ctypes.windll
d.user32.OpenClipboard(0)
handle = d.user32.GetClipboardData(CF_UNICODETEXT)
text = ctypes.c_wchar_p(handle).value
d.user32.CloseClipboard()
return text
これにはもっと簡単な解決策があると思います。
name = input('What is your name? ')
print('Hello %s' % (name) )
次に、コマンドラインでプログラムを実行します
python greeter.py |クリップ
これにより、ファイルの出力がクリップボードにパイプされます
ウィジェットには、クリップボードの内容を返す.clipboard_get()
という名前のメソッドもあります(クリップボード内のデータのタイプに基づいて何らかのエラーが発生しない限り)。
clipboard_get()
メソッドは、このバグレポートで言及されています。
http://bugs.python.org/issue14777
奇妙なことに、この方法は、私が通常参照する一般的な(ただし非公式の)オンラインTkInterドキュメントソースには記載されていません。
モジュール clipboard
を使用できます。そのシンプルで非常に使いやすい。 Mac、Windows、&Linux。
注:pyperclip
の代替
インストール後、インポートします:
import clipboard
その後、次のようにコピーできます。
clipboard.copy("This is copied")
コピーしたテキストを貼り付けることもできます。
clipboard.paste()
これはatomizerの改善された答えです。
注update()
と200 ms
の2つの呼び出しは、それらの間の遅延です。クリップボードの不安定な状態により、凍結アプリケーションを保護します。
from Tkinter import Tk
impor time
r = Tk()
r.withdraw()
r.clipboard_clear()
r.clipboard_append('some string')
r.update()
time.sleep(.2)
r.update()
r.destroy()
import wx
def ctc(text):
if not wx.TheClipboard.IsOpened():
wx.TheClipboard.Open()
data = wx.TextDataObject()
data.SetText(text)
wx.TheClipboard.SetData(data)
wx.TheClipboard.Close()
ctc(text)
ここで共有するスニペットは、テキストファイルをフォーマットする機能を利用しています。複雑な出力をクリップボードにコピーする場合はどうでしょうか。 (列のnumpy配列または何かのリストを言う)
import subprocess
import os
def cp2clip(clist):
#create a temporary file
fi=open("thisTextfileShouldNotExist.txt","w")
#write in the text file the way you want your data to be
for m in clist:
fi.write(m+"\n")
#close the file
fi.close()
#send "clip < file" to the Shell
cmd="clip < thisTextfileShouldNotExist.txt"
w = subprocess.check_call(cmd,Shell=True)
#delete the temporary text file
os.remove("thisTextfileShouldNotExist.txt")
return w
windowsでのみ動作し、LinuxやMacに適応できると思います。たぶん少し複雑です...
例:
>>>cp2clip(["ET","phone","home"])
>>>0
任意のテキストエディターでCtrl + V:
ET
phone
home