Я пытаюсь создать базовое приложение для Windows, которое строит строку из пользовательского ввода, а затем добавляет ее в буфер обмена. Как скопировать строку в буфер обмена с помощью Python?
Как скопировать строку в буфер обмена в Windows с помощью Python?
Ответ 1
Собственно, pywin32 и ctypes кажутся излишними для этой простой задачи. Tkinter - это кросс-платформенная среда графического интерфейса, которая по умолчанию поставляется с 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.
Ответ 2
У меня не было решения, просто обходной путь.
 Windows Vista имеет встроенную команду под названием clip которая выводит команду команды из командной строки и помещает ее в буфер обмена. Например, ipconfig | clip ipconfig | clip.
 Поэтому я сделал функцию с модулем os который берет строку и добавляет ее в буфер обмена, используя встроенное решение для Windows.
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.
 Как отмечалось ранее в комментариях, одним из недостатков этого подхода является то, что команда echo автоматически добавляет новую строку в конец вашего текста. Чтобы этого избежать, вы можете использовать измененную версию команды:
def addToClipBoard(text):
    command = 'echo | set /p nul=' + text.strip() + '| clip'
    os.system(command)
 Если вы используете Windows XP, он будет работать сразу после выполнения шагов копирования и вставки из командной строки Windows XP Pro прямо в буфер обмена.
Ответ 3
Вы также можете использовать 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()
		Ответ 4
Вы можете использовать pyperclip - кросс-платформенный модуль буфера обмена. Или Xerox - аналогичный модуль, за исключением того, что модуль win32 Python работает в Windows.
Ответ 5
Вы можете использовать отличный pandas, который имеет встроенную поддержку буфера обмена, но вам нужно пройти через DataFrame.
import pandas as pd
df=pd.DataFrame(['Text to copy'])
df.to_clipboard(index=False,header=False)
		Ответ 6
Самый простой способ - использовать pyperclip. Работает в Python 2 и 3.
Чтобы установить эту библиотеку, используйте:
pip install pyperclip
Пример использования:
import pyperclip
pyperclip.copy("your string")
Если вы хотите получить содержимое буфера обмена:
clipboard_content = pyperclip.paste()
		Ответ 7
Похоже, вам нужно добавить win32clipboard к вашим сайтам. Это часть пакета pywin32
Ответ 8
По какой-то причине я никогда не мог заставить решение 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, и работает даже с emoji, например \U0001f601 (😁).
Ответ 9
Я пробовал различные решения, но это самый простой, который передает мой тест:
#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 __name__ == "__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'))
Протестировано OK в Python 3.4 на Windows 8.1 и Python 2.7 на Windows 7. Также при чтении данных Unicode с помощью строк в Unix, скопированных из Windows. Скопированные данные остаются в буфере обмена после выхода 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
		Ответ 10
В виджетах также есть метод с именем .clipboard_get(), который возвращает содержимое буфера обмена (если какая-либо ошибка не происходит на основе типа данных в буфере обмена).
Метод clipboard_get() упоминается в этом отчете об ошибке: 
http://bugs.python.org/issue14777
Как ни странно, этот метод не упоминался в общих (но неофициальных) онлайн-источниках документации TkInter, на которые я обычно ссылаюсь.
Ответ 11
Я думаю, что есть намного более простое решение.
name = input('What is your name? ')
print('Hello %s' % (name) )
Затем запустите свою программу в командной строке
python greeter.py | Клип
Это приведет к выходу файла вашего файла в буфер обмена
Ответ 12
Вы можете использовать модуль clipboard. Это просто и чрезвычайно удобно в использовании. Работает с Mac, Windows и & Linux.
Примечание: это альтернатива pyperclip
После установки импортируйте его:
import clipboard
Затем вы можете скопировать так:
clipboard.copy("This is copied")
Вы также можете вставить скопированный текст:
clipboard.paste()
		Ответ 13
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)
		Ответ 14
Это улучшенный ответ распылителя.
Обратите внимание на 2 вызова update() и 200 ms задержки между ними. Они защищают приложения для замораживания из-за неустойчивого состояния буфера обмена:
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()
		Ответ 15
Фрагмент, которым я поделился здесь, использует возможность форматирования текстовых файлов: что, если вы хотите скопировать сложный вывод в буфер обмена? (Скажем, массив в столбце или список чего-то)
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
		Ответ 16
В дополнение к Марку Рэнсому ответьте, используя ctypes: Это не работает для (всех?) Систем x64, так как дескрипторы кажутся усеченными до размера int. Явное определение аргументов и возвращаемых значений помогает решить эту проблему.
import ctypes
import ctypes.wintypes as w
CF_UNICODETEXT = 13
u32 = ctypes.WinDLL('user32')
k32 = ctypes.WinDLL('kernel32')
OpenClipboard = u32.OpenClipboard
OpenClipboard.argtypes = w.HWND,
OpenClipboard.restype = w.BOOL
GetClipboardData = u32.GetClipboardData
GetClipboardData.argtypes = w.UINT,
GetClipboardData.restype = w.HANDLE
EmptyClipboard = u32.EmptyClipboard
EmptyClipboard.restype = w.BOOL
SetClipboardData = u32.SetClipboardData
SetClipboardData.argtypes = w.UINT, w.HANDLE,
SetClipboardData.restype = w.HANDLE
CloseClipboard = u32.CloseClipboard
CloseClipboard.argtypes = None
CloseClipboard.restype = w.BOOL
GHND = 0x0042
GlobalAlloc = k32.GlobalAlloc
GlobalAlloc.argtypes = w.UINT, w.ctypes.c_size_t,
GlobalAlloc.restype = w.HGLOBAL
GlobalLock = k32.GlobalLock
GlobalLock.argtypes = w.HGLOBAL,
GlobalLock.restype = w.LPVOID
GlobalUnlock = k32.GlobalUnlock
GlobalUnlock.argtypes = w.HGLOBAL,
GlobalUnlock.restype = w.BOOL
GlobalSize = k32.GlobalSize
GlobalSize.argtypes = w.HGLOBAL,
GlobalSize.restype = w.ctypes.c_size_t
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(GHND, len(data) + 2)
    pcontents = GlobalLock(handle)
    ctypes.memmove(pcontents, data, len(data))
    GlobalUnlock(handle)
    SetClipboardData(CF_UNICODETEXT, handle)
    CloseClipboard()
#Test run
paste = get
copy = put
copy("Hello World!")
print(paste())
		Ответ 17
Фрагмент кода для копирования буфера обмена:
Создайте код оболочки Python в модуле с именем (clipboard.py):
import clr
clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import Clipboard
def setText(text):
    Clipboard.SetText(text)
def getText():
    return Clipboard.GetText()
Затем импортируйте указанный выше модуль в свой код.
import io
import clipboard
code = clipboard.getText()
print code
code = "abcd"
clipboard.setText(code)
Я должен отдать должное сообщению в блоге Доступ к буферам обмена в IronPython.
Ответ 18
вы можете попробовать следующее:
command = 'echo content |clip'
subprocess.check_call(command, shell=True)
		Ответ 19
from Tkinter import Tk
clip = Tk()