Как скопировать строку в буфер обмена в Windows с помощью Python?
Я пытаюсь сделать базовое приложение Windows, которое строит строку из пользовательского ввода, а затем добавляет ее в буфер обмена. Как скопировать строку в буфер обмена с помощью Python?
16 ответов
на самом деле 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
.
поэтому я сделал функцию с 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 прямо в буфер обмена.
вы также можете использовать ctypes, чтобы подключиться к API Windows и избежать массивного пакета 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()
можно использовать pyperclip - кросс-платформенный модуль буфера обмена. Или компания Xerox - аналогичный модуль, за исключением того, что требуется модуль win32 Python для работы в Windows.
вы можете использовать отличные панды, которые имеют встроенную поддержку буфера обмена, но вам нужно пройти через фрейм данных.
import pandas as pd
df=pd.DataFrame(['Text to copy'])
df.to_clipboard(index=False,header=False)
похоже, вам нужно добавить win32clipboard на ваш сайт-пакеты. Это часть пакета pywin32
по какой-то причине я никогда не мог заставить решение 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'')
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
вышеизложенное изменилось с момента первого создания этого ответа, чтобы лучше справляться с расширенными символами Юникода и Python 3. Он был протестирован в Python 2.7 и 3.5 и работает даже с emoji, такими как \U0001f601 ()
.
Я пробовал различные решения, но это самый простой, который проходит мой тест:
#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 linefeeds, скопированных из 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
самый простой способ-с pyperclip. Работает в python 2 и 3.
чтобы установить эту библиотеку, используйте:
pip install pyperclip
пример использования:
import pyperclip
pyperclip.copy("your string")
Если вы хотите получить содержимое буфера обмена:
clipboard_content = pyperclip.paste()
виджеты также имеют метод с именем .clipboard_get()
Это возвращает содержимое буфера обмена (если только какая-либо ошибка не происходит в зависимости от типа данных в буфере обмена).
на clipboard_get()
метод упоминается в этом отчете об ошибке:
http://bugs.python.org/issue14777
Как ни странно, этот метод не был упомянут в общих (но неофициальных) онлайн-источниках документации TkInter, на которые я обычно ссылаюсь.
Я думаю, что есть гораздо более простое решение для этого.
name = input('What is your name? ')
print('Hello %s' % (name) )
затем запустите программу в командной строке
python greeter.py / клип
это передаст вывод вашего файла в буфер обмена
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)
фрагмент кода для копирования буфера обмена:
создать оболочку 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.
это улучшенный ответ распылитель.
примечание 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()
вы можете попробовать это:
command = 'echo content |clip'
subprocess.check_call(command, shell=True)