Я намагаюся зробити базовий додаток для 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"
Хоча це може мати проблеми в системах з вікнами старше 95
type
. Я пишу свій текст у файл і використовую команду type myfile.txt | clip
.
Ви також можете використовувати 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()
bytes(data,"ascii")
до bytes(data)
. Дякую за відповідь на запитання, я не можу використовувати pywin32 або tk або ряд інших речей, і це працює.
bytes(data, "mbcs")
буде працювати з кодуванням Windows за замовчуванням. Дозволено завантажити це в буфер обміну "másreas ç saod é í ó u* ü ö ï/"
і правильно прочитати його назад.
Можна використовувати pyperclip - модуль міжплатформового буфера обміну. Або Xerox - подібний модуль, за винятком того, що для роботи в Windows потрібен модуль Win32 Python.
pyperclip
не робить Unicode в Windows. win32clipboard
робить.
pyperclip
пластир був прийнятий; c:\python34\Scripts\pip install --upgrade pyperclip
для обробки тексту Unicode.
pyperclip
, ні paperclip
. Також, як і в 2016 році, pyperclip працює і з символами Unicode. Я перевірив символи ± ° ©★ αβγθΔΨΦåäö для роботи над Win10 64-бітними, з 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
не працює. Тому я не згоден з "кращим використанням піперліпса".
import pandas.io.clipboard as pyperclip
або назвати його все, що завгодно. Ось де він сидить pandas
, як мінімум,
Найпростіший спосіб - за допомогою піперліпса . Працює в пітонах 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 за допомогою Unife ліній передач, скопійованих з 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()
Функція також потребує в роботі; смайли "📋" (\ U0001f400) копіюється як "🐀" (\ U0001f4cb) або "📋." перетворюється на "📋".
Схоже, вам потрібно додати win32clipboard до своїх сайтів-пакетів. Це частина пакету pywin32
Ви можете використовувати модуль clipboard
. Його простий і надзвичайно простий у використанні. Працює з Mac , Windows та Linux .
Примітка: його альтернативаpyperclip
Після встановлення імпортуйте його:
import clipboard
Потім ви можете скопіювати так:
clipboard.copy("This is copied")
Ви також можете вставити скопійований текст:
clipboard.paste()
pip install clipboard
.
У віджетах також є метод, який називається, .clipboard_get()
який повертає вміст буфера обміну (якщо тільки якась помилка не трапляється на основі типу даних у буфері обміну).
clipboard_get()
Метод згадується в цьому повідомленні про помилку:
http://bugs.python.org/issue14777
Як не дивно, цей метод не згадувався в поширених (але неофіційних) Інтернет-документаціях TkInter, на які я зазвичай посилаюся.
Я думаю, що для цього є набагато простіше рішення.
name = input('What is your name? ')
print('Hello %s' % (name) )
Потім запустіть програму в командному рядку
пітон 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()