Как скопировать строку в буфер обмена в Windows с помощью Python?
Я пытаюсь сделать базовое приложение Windows, которое строит строку из пользовательского ввода, а затем добавляет ее в буфер обмена. Как скопировать строку в буфер обмена с помощью Python?
16 ответов:
на самом деле
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
.
у меня не было решения, просто обходной путь.
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()
вы можете использовать отличные панды, которые имеют встроенную поддержку буфера обмена, но вам нужно пройти через фрейм данных.
import pandas as pd df=pd.DataFrame(['Text to copy']) df.to_clipboard(index=False,header=False)
похоже, вам нужно добавить win32clipboard на ваш сайт-пакеты. Это часть пакета pywin32
по какой-то причине я никогда не мог заставить решение Tk работать на меня. решение капаче гораздо более работоспособен, но форматирование противоречит моему стилю и не работает с 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 linefeed, скопированных из 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()
что возвращает содержимое буфера обмена (если какая-то ошибка происходит на основе типа данных в буфере обмена).The
clipboard_get()
метод упоминается в этом отчете об ошибке:
http://bugs.python.org/issue14777
Я думаю, что есть гораздо более простое решение для этого.
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()