Я пытаюсь создать простое приложение для Windows, которое создает строку из пользовательского ввода, а затем добавляет ее в буфер обмена. Как скопировать строку в буфер обмена с помощью Python?
Я пытаюсь создать простое приложение для 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
.
r.destroy()
. Как только я это называю, буфер обмена становится пустым, и нажатие Ctrl-V может привести к зависанию целевого приложения. (ОС: Windows 7 x64)
У меня не было решения, только обходной путь.
В 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 прямо в буфер обмена .
text
содержит | calc.exe
?
text with " quotes and | pipe
становится, "text with "" quotes and | pipe"
хотя это может иметь проблемы в системах с Windows старше 95 лет.
type
. Я записываю свой текст в файл и использую команду type myfile.txt | clip
.
Вы также можете использовать 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()
bytes(data,"ascii")
на bytes(data)
. Спасибо за ответ на вопрос, я не могу использовать pywin32 или tk или ряд других вещей, и это работает.
bytes(data, "mbcs")
будет работать с кодировкой Windows по умолчанию. Позволил мне загрузить это в буфер обмена "másreas ç saod é í ó u* ü ö ï/"
и прочитать его обратно правильно.
Вы можете использовать pyperclip - кроссплатформенный модуль буфера обмена. Или Xerox - аналогичный модуль, за исключением того, что для работы в Windows требуется модуль Python win32.
pyperclip
не выполняет Unicode в Windows. win32clipboard
делает.
pyperclip
патч был принят; c:\python34\Scripts\pip install --upgrade pyperclip
обрабатывать текст Unicode.
pyperclip
не так paperclip
. Также, как и в 2016 году, pyperclip работает и с символами Unicode. Я проверил символы ± ° ©---- αβγθΔΨΦåäö для работы на Win10 64-bit, с Python 3.5 и pyperclip 1.5.27.
Вы можете использовать отличные панды, которые имеют встроенную поддержку буфера обмена, но вам нужно пройти через DataFrame.
import pandas as pd
df=pd.DataFrame(['Text to copy'])
df.to_clipboard(index=False,header=False)
pyperclip
любом случае, так что лучше использоватьpyperpclip
pandas
это легко доступно, но import pyperclip
не работает. Так что я не согласен с «лучше использовать pyperclip».
import pandas.io.clipboard as pyperclip
или назвать его как хотите. Вот где он находится pandas
, по крайней мере
Самый простой способ - с помощью Pyperclip . Работает в питоне 2 и 3.
Чтобы установить эту библиотеку, используйте:
pip install pyperclip
Пример использования:
import pyperclip
pyperclip.copy("your string")
Если вы хотите получить содержимое буфера обмена:
clipboard_content = pyperclip.paste()
pyperclip
поставляется ли модуль с Python? Какие версии? Я не вижу этого в Python 2.7 ...
pyperclip.paste()
не работает с изображениями, просто возвращает NoneType
ошибку. но работает с правым кликом и копированием, а затем с помощью Python вставляет скопированные результаты.
Я пробовал различные решения, но это самое простое, которое проходит мой тест :
#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'))
Проверено нормально в 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
win32clipboard
? Это не часть моего Python 2.7. И почему paste
используют CF_TEXT
вместо CF_UNICODETEXT
?
По какой-то причине мне так и не удалось заставить решение 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 (😁)
.
put()
Функция также нуждается в работе; emoji "📋" (\ U0001f400) копируется как "🐀" (\ U0001f4cb) или "📋." превращается в «📋».
Похоже, вам нужно добавить win32clipboard к вашим сайт-пакетам. Это часть пакета pywin32
Вы можете использовать модуль clipboard
. Это просто и чрезвычайно удобно в использовании. Работает с Mac , Windows и Linux .
Примечание: это альтернативаpyperclip
После установки импортируйте его:
import clipboard
Затем вы можете скопировать так:
clipboard.copy("This is copied")
Вы также можете вставить скопированный текст:
clipboard.paste()
pip install clipboard
.
У виджетов также есть метод named, .clipboard_get()
который возвращает содержимое буфера обмена (если только не возникает какая-либо ошибка в зависимости от типа данных в буфере обмена).
clipboard_get()
Метод упоминается в этом сообщении об ошибке:
http://bugs.python.org/issue14777
Странно, но этот метод не упоминался в распространенных (но неофициальных) источниках документации TkInter, на которые я обычно ссылаюсь.
Я думаю, что есть гораздо более простое решение для этого.
name = input('What is your name? ')
print('Hello %s' % (name) )
Затем запустите вашу программу в командной строке
python greeter.py | клип
Это передаст вывод вашего файла в буфер обмена
В дополнение к ответу Марка Рэнсома с использованием 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())
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)
Фрагмент, которым я делюсь здесь, использует возможность форматирования текстовых файлов: что, если вы хотите скопировать сложный вывод в буфер обмена? (Скажем, массив в столбце или список чего-то)
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
Это улучшенный ответ распылителя .
Обратите внимание на 2 вызова update()
и 200 ms
задержку между ними. Они защищают приложения замораживания из-за нестабильного состояния буфера обмена:
from Tkinter import Tk
import time
r = Tk()
r.withdraw()
r.clipboard_clear()
r.clipboard_append('some string')
r.update()
time.sleep(.2)
r.update()
r.destroy()
Используйте библиотеку буфера обмена python!
import clipboard as cp
cp.copy("abc")
Буфер обмена содержит «abc» сейчас. Счастливого вставки!
Не все ответы работали для моих различных конфигураций Python, поэтому это решение использует только модуль подпроцесса. Тем copy_keyword
не менее, должно быть pbcopy
для Mac или clip
для Windows:
import subprocess
subprocess.run('copy_keyword', universal_newlines=True, input='New Clipboard Value 😀')
Вот еще более обширный код, который автоматически проверяет текущую операционную систему:
import platform
import subprocess
copy_string = 'New Clipboard Value 😀'
# Check which operating system is running to get the correct copying keyword.
if platform.system() == 'Darwin':
copy_keyword = 'pbcopy'
elif platform.system() == 'Windows':
copy_keyword = 'clip'
subprocess.run(copy_keyword, universal_newlines=True, input=copy_string)
Вы можете использовать модуль winclip32! установить:
pip install winclip32
копировать:
import winclip32
winclip32.set_clipboard_data(winclip32.UNICODE_STD_TEXT, "some text")
получить:
import winclip32
print(winclip32.get_clipboard_data(winclip32.UNICODE_STD_TEXT))
для получения дополнительной информации: https://pypi.org/project/winclip32/
Фрагмент кода для копирования в буфер обмена:
Создайте код оболочки 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 .
from Tkinter import Tk
clip = Tk()