Estou tentando criar um aplicativo básico do Windows que crie uma cadeia de caracteres da entrada do usuário e a adicione à área de transferência. Como copiar uma string para a área de transferência usando Python?
Estou tentando criar um aplicativo básico do Windows que crie uma cadeia de caracteres da entrada do usuário e a adicione à área de transferência. Como copiar uma string para a área de transferência usando Python?
Respostas:
Na verdade, pywin32
e ctypes
parece ser um exagero para esta tarefa simples. Tkinter
é uma estrutura de GUI de plataforma cruzada, que é fornecida com o Python por padrão e possui métodos de acesso à área de transferência junto com outras coisas interessantes.
Se tudo o que você precisa é colocar algum texto na área de transferência do sistema, isso será feito:
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()
E isso é tudo, não há necessidade de mexer com bibliotecas de terceiros específicas da plataforma.
Se você estiver usando o Python 3, substitua TKinter
por tkinter
.
r.destroy()
. Depois que chamo isso, a área de transferência fica vazia e pressionar Ctrl-V pode fazer com que o aplicativo de destino congele. (OS: Windows 7 x64)
Eu não tinha uma solução, apenas uma solução alternativa.
O Windows Vista em diante tem um comando embutido chamado clip
que pega a saída de um comando da linha de comando e o coloca na área de transferência. Por exemplo ipconfig | clip
,.
Então, criei uma função com o os
módulo que pega uma string e a adiciona à área de transferência usando a solução embutida do 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.
Como observado anteriormente nos comentários, no entanto, uma desvantagem dessa abordagem é que o echo
comando adiciona automaticamente uma nova linha ao final do seu texto. Para evitar isso, você pode usar uma versão modificada do comando:
def addToClipBoard(text):
command = 'echo | set /p nul=' + text.strip() + '| clip'
os.system(command)
Se você estiver usando o Windows XP, ele funcionará apenas seguindo as etapas em Copiar e colar do prompt de comando do Windows XP Pro direto para a Área de transferência .
text
contiver | calc.exe
?
text with " quotes and | pipe
torna-se "text with "" quotes and | pipe"
Embora este pode ter problemas em sistemas com janelas com idade superior a 95.
type
. Eu escrevo meu texto para o arquivo, e use o comando type myfile.txt | clip
.
Você também pode usar ctypes para acessar a API do Windows e evitar o enorme pacote pywin32. É isso que eu uso (desculpe o estilo ruim, mas a ideia está aí):
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")
para bytes(data)
. Obrigado por responder à pergunta, não posso usar pywin32 ou tk ou várias outras coisas e isso funciona.
bytes(data, "mbcs")
funcionará com a codificação padrão do Windows. Permitiu-me carregar isso na área de transferência "másreas ç saod é í ó u* ü ö ï/"
e lê-lo novamente corretamente.
Você pode usar o pyperclip - módulo de transferência de plataforma cruzada. Ou Xerox - módulo semelhante, exceto que o módulo win32 Python funciona no Windows.
pyperclip
não executa Unicode no Windows. win32clipboard
faz.
pyperclip
adesivo foi aceito; c:\python34\Scripts\pip install --upgrade pyperclip
para lidar com texto Unicode.
pyperclip
não é isso paperclip
. Além disso, como em 2016, o pyperclip também funciona com caracteres Unicode. Testei caracteres ± ° © Rue αβγθΔΨΦåäö para trabalhar no Win10 de 64 bits, com Python 3.5 e pyperclip 1.5.27.
Você pode usar os excelentes pandas, que possuem suporte à área de transferência, mas precisam passar por um DataFrame.
import pandas as pd
df=pd.DataFrame(['Text to copy'])
df.to_clipboard(index=False,header=False)
pyperclip
de qualquer maneira, então é melhor usopyperpclip
pandas
está prontamente disponível, mas import pyperclip
não funciona. Portanto, não concordo com "melhor uso do pyperclip".
import pandas.io.clipboard as pyperclip
ou nomeá-lo como quiser. É aí que ele fica dentro pandas
, pelo menos
A maneira mais simples é com o pyperclip . Funciona em python 2 e 3.
Para instalar esta biblioteca, use:
pip install pyperclip
Exemplo de uso:
import pyperclip
pyperclip.copy("your string")
Se você deseja obter o conteúdo da área de transferência:
clipboard_content = pyperclip.paste()
pyperclip
módulo vem com Python? Quais versões? Eu não vê-lo em Python 2.7 ...
pyperclip.paste()
não funciona com imagens apenas retorna NoneType
erro. mas funciona com o botão direito e a cópia e, em seguida, usando python para colar os resultados copiados.
Eu tentei várias soluções, mas esta é a mais simples que passa no meu teste :
#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'))
Testado OK no Python 3.4 no Windows 8.1 e Python 2.7 no Windows 7. Também ao ler dados Unicode com feeds de linha Unix copiados do Windows. Os dados copiados permanecem na área de transferência após a saída do Python:"Testing
the “clip—board”: 📋"
Se você não deseja dependências externas, use este código (agora parte da plataforma cruzada 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
? Não faz parte do meu Python 2.7. E por que paste
usar em CF_TEXT
vez de CF_UNICODETEXT
?
Por alguma razão, nunca consegui fazer com que a solução Tk funcionasse para mim. A solução do kapace é muito mais viável, mas a formatação é contrária ao meu estilo e não funciona com o Unicode. Aqui está uma versão modificada.
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
O acima foi alterado desde que essa resposta foi criada, para melhor lidar com caracteres Unicode estendidos e Python 3. Foi testado no Python 2.7 e 3.5 e funciona mesmo com emoji como \U0001f601 (😁)
.
put()
função também precisa de trabalho; o emoji "📋" (\ U0001f400) é copiado como "🐀" (\ U0001f4cb) ou "📋". passa para "📋".
Parece que você precisa adicionar o win32clipboard aos seus pacotes de sites. Faz parte do pacote pywin32
Você pode usar o módulo clipboard
. É simples e extremamente fácil de usar. Funciona com Mac , Windows e Linux .
Nota: É uma alternativa depyperclip
Após a instalação, importe-o:
import clipboard
Então você pode copiar assim:
clipboard.copy("This is copied")
Você também pode colar o texto copiado:
clipboard.paste()
pip install clipboard
.
Aqui está a maneira mais fácil e confiável que encontrei se você estiver bem, dependendo dos pandas. No entanto, não acho que isso faça parte oficialmente da API do Pandas, por isso pode ser interrompido com futuras atualizações. Funciona a partir de 0.25.3
from pandas.io.clipboard import copy
copy("test")
Os widgets também têm um método nomeado .clipboard_get()
que retorna o conteúdo da área de transferência (a menos que ocorra algum tipo de erro com base no tipo de dados na área de transferência).
O clipboard_get()
método é mencionado neste relatório de bug:
http://bugs.python.org/issue14777
Estranhamente, esse método não foi mencionado nas fontes comuns (mas não oficiais) de documentação on-line do TkInter às quais costumo me referir.
Eu acho que existe uma solução muito mais simples para isso.
name = input('What is your name? ')
print('Hello %s' % (name) )
Em seguida, execute seu programa na linha de comando
python greeter.py | grampo
Isso direcionará a saída do seu arquivo para a área de transferência
Além da resposta de Mark Ransom usando ctypes: Isso não funciona para sistemas x64 (todos?), Pois os identificadores parecem estar truncados no tamanho int. A definição explícita de argumentos e valores de retorno ajuda a superar esse problema.
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)
O trecho que eu compartilho aqui aproveita a capacidade de formatar arquivos de texto: e se você quiser copiar uma saída complexa para a área de transferência? (Diga uma matriz numpy na coluna ou uma lista de algo)
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
funciona apenas para windows, pode ser adaptado para linux ou mac, eu acho. Talvez um pouco complicado ...
exemplo:
>>>cp2clip(["ET","phone","home"])
>>>0
Ctrl + V em qualquer editor de texto:
ET
phone
home
Esta é a resposta melhorada do atomizador .
Nota 2 chamadas update()
e 200 ms
atraso entre elas. Eles protegem os aplicativos de congelamento devido a um estado instável da área de transferência:
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()
Use a biblioteca de transferência da python!
import clipboard as cp
cp.copy("abc")
A área de transferência contém 'abc' agora. Colagem feliz!
Nem todas as respostas funcionaram para minhas várias configurações de python; portanto, esta solução usa apenas o módulo de subprocesso. No entanto, copy_keyword
deve ser pbcopy
para Mac ou clip
Windows:
import subprocess
subprocess.run('copy_keyword', universal_newlines=True, input='New Clipboard Value 😀')
Aqui está um código mais extenso que verifica automaticamente qual é o sistema operacional atual:
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)
Você pode usar o módulo winclip32! instalar:
pip install winclip32
copiar:
import winclip32
winclip32.set_clipboard_data(winclip32.UNICODE_STD_TEXT, "some text")
para obter:
import winclip32
print(winclip32.get_clipboard_data(winclip32.UNICODE_STD_TEXT))
para mais informações: https://pypi.org/project/winclip32/
Fragmento de código para copiar a área de transferência:
Crie um código Python de wrapper em um módulo chamado ( 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()
Em seguida, importe o módulo acima para o seu código.
import io
import clipboard
code = clipboard.getText()
print code
code = "abcd"
clipboard.setText(code)
Devo dar crédito à postagem do blog Clipboard Access no IronPython .
from Tkinter import Tk
clip = Tk()