web-dev-qa-db-ja.com

Pythonを使用してWindowsで文字列をクリップボードにコピーするにはどうすればよいですか?

ユーザー入力から文字列を構築し、クリップボードに追加する基本的なWindowsアプリケーションを作成しようとしています。 Pythonを使用して文字列をクリップボードにコピーするにはどうすればよいですか?

164
tester

実際、pywin32ctypesは、この単純なタスクには過剰すぎるようです。 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を使用している場合は、TKintertkinterに置き換えます。

255
atomizer

解決策はありませんでしたが、回避策がありました。

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のコマンドプロンプトをクリップボードに直接入力する

74
user1227883

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()
39
kapace

pyperclip -クロスプラットフォームクリップボードモジュールを使用できます。または Xerox -Windows上で動作するためにwin32 Pythonモジュールを必要とする以外は同様のモジュール。

27
pongo

組み込みのクリップボードサポートを備えた優れたパンダを使用できますが、DataFrameを渡す必要があります。

import pandas as pd
df=pd.DataFrame(['Text to copy'])
df.to_clipboard(index=False,header=False)
21
Gadi Oron

なんらかの理由で、私は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 (????)など。

10
Mark Ransom

サイトパッケージにwin32clipboardを追加する必要があるようです。 pywin32パッケージ の一部です

10
Jason Coon

最も簡単な方法は pyperclip を使用することです。 python 2および3で動作します。

このライブラリをインストールするには、次を使用します。

pip install pyperclip

使用例:

import pyperclip

pyperclip.copy("your string")

クリップボードの内容を取得する場合:

clipboard_content = pyperclip.paste()
10
maviz

さまざまな解決策を試しましたが、これは 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
9
Cees Timmerman

これにはもっと簡単な解決策があると思います。

name = input('What is your name? ')
print('Hello %s' % (name) )

次に、コマンドラインでプログラムを実行します

python greeter.py |クリップ

これにより、ファイルの出力がクリップボードにパイプされます

3
jdeyrup

ウィジェットには、クリップボードの内容を返す.clipboard_get()という名前のメソッドもあります(クリップボード内のデータのタイプに基づいて何らかのエラーが発生しない限り)。

clipboard_get()メソッドは、このバグレポートで言及されています。
http://bugs.python.org/issue14777

奇妙なことに、この方法は、私が通常参照する一般的な(ただし非公式の)オンラインTkInterドキュメントソースには記載されていません。

3
mpb

モジュール clipboard を使用できます。そのシンプルで非常に使いやすい。 MacWindows、&Linux
注:pyperclipの代替

インストール後、インポートします:

import clipboard

その後、次のようにコピーできます。

clipboard.copy("This is copied")

コピーしたテキストを貼り付けることもできます。

clipboard.paste()
1
Black Thunder

これは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()
0
MarianD
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)
0
jlk

ここで共有するスニペットは、テキストファイルをフォーマットする機能を利用しています。複雑な出力をクリップボードにコピーする場合はどうでしょうか。 (列の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
0
thomasJeanne