Estoy tratando de hacer una aplicación básica de Windows que construya una cadena a partir de la entrada del usuario y luego la agregue al portapapeles. ¿Cómo copio una cadena al portapapeles usando Python?
Estoy tratando de hacer una aplicación básica de Windows que construya una cadena a partir de la entrada del usuario y luego la agregue al portapapeles. ¿Cómo copio una cadena al portapapeles usando Python?
Respuestas:
En realidad, pywin32
y ctypes
parece ser una exageración para esta simple tarea. Tkinter
es un marco GUI multiplataforma, que se entrega con Python por defecto y tiene métodos de acceso al portapapeles junto con otras cosas interesantes.
Si todo lo que necesita es poner algo de texto en el portapapeles del sistema, esto lo hará:
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()
Y eso es todo, no es necesario perder el tiempo con las bibliotecas de terceros específicas de la plataforma.
Si está utilizando Python 3, reemplácelo TKinter
con tkinter
.
r.destroy()
. Una vez que llamo a eso, el portapapeles se vacía y presionar Ctrl-V puede hacer que la aplicación de destino se congele. (SO: Windows 7 x64)
No tenía una solución, solo una solución.
Windows Vista en adelante tiene un comando incorporado llamado clip
que toma la salida de un comando de la línea de comando y lo coloca en el portapapeles. Por ejemplo, ipconfig | clip
.
Entonces hice una función con el os
módulo que toma una cadena y la agrega al portapapeles usando la solución incorporada de 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.
Sin embargo, como se señaló anteriormente en los comentarios, una desventaja de este enfoque es que el echo
comando agrega automáticamente una nueva línea al final de su texto. Para evitar esto, puede usar una versión modificada del comando:
def addToClipBoard(text):
command = 'echo | set /p nul=' + text.strip() + '| clip'
os.system(command)
Si está utilizando Windows XP, funcionará siguiendo los pasos de Copiar y pegar desde el símbolo del sistema de Windows XP Pro directamente al Portapapeles .
text
contiene | calc.exe
?
text with " quotes and | pipe
se convierte "text with "" quotes and | pipe"
Aunque esto puede tener problemas en sistemas con ventanas mayores de 95.
type
. Escribo mi texto en el archivo y uso el comando type myfile.txt | clip
.
También puede usar ctypes para acceder a la API de Windows y evitar el paquete masivo pywin32. Esto es lo que uso (disculpe el mal estilo, pero la idea está ahí):
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")
a bytes(data)
. Gracias por responder la pregunta, no puedo usar pywin32 o tk o una serie de otras cosas y esto funciona.
bytes(data, "mbcs")
funcionará con la codificación predeterminada de Windows. Me permitió cargar esto en el portapapeles "másreas ç saod é í ó u* ü ö ï/"
y volver a leerlo correctamente.
Puede usar pyperclip - módulo de portapapeles multiplataforma. O Xerox : módulo similar, excepto que requiere que el módulo win32 Python funcione en Windows.
pyperclip
no hace Unicode en Windows. win32clipboard
hace.
pyperclip
parche fue aceptado; c:\python34\Scripts\pip install --upgrade pyperclip
para manejar texto Unicode.
pyperclip
así paperclip
. Además, como en 2016, pyperclip también funciona con caracteres Unicode. He probado los caracteres ± ° © ® αβγθΔΨΦåäö para trabajar en Win10 de 64 bits, con Python 3.5 y pyperclip 1.5.27.
Puede usar los excelentes pandas, que tienen un soporte de portapapeles incorporado, pero necesita pasar por un DataFrame.
import pandas as pd
df=pd.DataFrame(['Text to copy'])
df.to_clipboard(index=False,header=False)
pyperclip
todos modos, así que mejor usopyperpclip
pandas
está disponible pero import pyperclip
no funciona. Así que no estoy de acuerdo con "mejor uso de pyperclip".
import pandas.io.clipboard as pyperclip
o nombrarlo como desee. Ahí es donde se encuentra pandas
, al menos
La forma más simple es con pyperclip . Funciona en python 2 y 3.
Para instalar esta biblioteca, use:
pip install pyperclip
Ejemplo de uso:
import pyperclip
pyperclip.copy("your string")
Si desea obtener el contenido del portapapeles:
clipboard_content = pyperclip.paste()
pyperclip
módulo viene con Python? Que versiones No lo veo en Python 2.7 ...
pyperclip.paste()
no funciona con imágenes solo devuelve NoneType
error. pero funciona con clic derecho y copia y luego usando python para pegar los resultados copiados.
He probado varias soluciones, pero esta es la más simple que pasa mi prueba :
#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'))
Probado OK en Python 3.4 en Windows 8.1 y Python 2.7 en Windows 7. También al leer datos Unicode con avances de línea Unix copiados de Windows. Los datos copiados permanecen en el portapapeles después de que Python sale:"Testing
the “clip—board”: 📋"
Si quieres sin dependencias externas, utilizar este código (ahora parte de multiplataforma 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
? No es parte de mi Python 2.7. ¿Y por qué paste
usar en CF_TEXT
lugar de CF_UNICODETEXT
?
Por alguna razón, nunca he podido hacer que la solución Tk funcione para mí. La solución de kapace es mucho más viable, pero el formato es contrario a mi estilo y no funciona con Unicode. Aquí hay una versión 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
Lo anterior ha cambiado desde que se creó esta respuesta por primera vez, para hacer frente mejor a los caracteres Unicode extendidos y Python 3. Se ha probado en Python 2.7 y 3.5, y funciona incluso con emoji como \U0001f601 (😁)
.
put()
función también necesita trabajo; el emoji "📋" (\ U0001f400) se copia como "🐀" (\ U0001f4cb) o "📋". se convierte en "📋".
Parece que necesita agregar win32clipboard a sus paquetes de sitio. Es parte del paquete pywin32
Puedes usar el módulo clipboard
. Es simple y extremadamente fácil de usar. Funciona con Mac , Windows y Linux .
Nota: es una alternativa depyperclip
Después de instalar, impórtelo:
import clipboard
Entonces puedes copiar así:
clipboard.copy("This is copied")
También puede pegar el texto copiado:
clipboard.paste()
pip install clipboard
.
Esta es la forma más fácil y confiable que encontré si estás bien dependiendo de Pandas. Sin embargo, no creo que esto sea oficialmente parte de la API de Pandas, por lo que puede romperse con futuras actualizaciones. Funciona a partir de 0.25.3
from pandas.io.clipboard import copy
copy("test")
Los widgets también tienen un método con nombre .clipboard_get()
que devuelve el contenido del portapapeles (a menos que ocurra algún tipo de error en función del tipo de datos en el portapapeles).
El clipboard_get()
método se menciona en este informe de error:
http://bugs.python.org/issue14777
Curiosamente, este método no se mencionó en las fuentes de documentación de TkInter en línea comunes (pero no oficiales) a las que generalmente me refiero.
Creo que hay una solución mucho más simple para esto.
name = input('What is your name? ')
print('Hello %s' % (name) )
Luego ejecute su programa en la línea de comando
python greeter.py | acortar
Esto canalizará la salida de su archivo al portapapeles
Además de la respuesta de Mark Ransom utilizando ctypes: esto no funciona para (¿todos?) Sistemas x64 ya que los controladores parecen estar truncados a int-size. La definición explícita de args y valores de retorno ayuda a superar este 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)
El fragmento que comparto aquí aprovecha la capacidad de formatear archivos de texto: ¿qué sucede si desea copiar una salida compleja en el portapapeles? (Diga una matriz numpy en la columna o una 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 solo para Windows, se puede adaptar para Linux o Mac, supongo. Quizás un poco complicado ...
ejemplo:
>>>cp2clip(["ET","phone","home"])
>>>0
Ctrl + V en cualquier editor de texto:
ET
phone
home
Esta es la respuesta mejorada del atomizador .
Nota 2 llamadas de update()
y 200 ms
retraso entre ellos. Protegen las aplicaciones de congelación debido a un estado inestable del portapapeles:
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()
¡Usa la biblioteca del portapapeles de Python!
import clipboard as cp
cp.copy("abc")
Portapapeles contiene 'abc' ahora. ¡Feliz pegado!
No todas las respuestas funcionaron para mis diversas configuraciones de Python, por lo que esta solución solo usa el módulo de subproceso. Sin embargo, copy_keyword
tiene que ser pbcopy
para Mac o clip
para Windows:
import subprocess
subprocess.run('copy_keyword', universal_newlines=True, input='New Clipboard Value 😀')
Aquí hay un código más extenso que verifica automáticamente cuál es el sistema operativo actual:
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)
¡Puedes usar el módulo winclip32! Instalar en pc:
pip install winclip32
copiar:
import winclip32
winclip32.set_clipboard_data(winclip32.UNICODE_STD_TEXT, "some text")
Llegar:
import winclip32
print(winclip32.get_clipboard_data(winclip32.UNICODE_STD_TEXT))
Para más información: https://pypi.org/project/winclip32/
Fragmento de código para copiar el portapapeles:
Cree un código de Python envoltorio en un módulo llamado ( 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()
Luego importe el módulo anterior a su código.
import io
import clipboard
code = clipboard.getText()
print code
code = "abcd"
clipboard.setText(code)
Debo dar crédito a la entrada del blog Clipboard Access en IronPython .
from Tkinter import Tk
clip = Tk()