¿Cómo copio una cadena al portapapeles en Windows usando Python?
clipboard (16)
Intento crear una aplicación básica de Windows que genere una cadena de entrada del usuario y luego la agregue al portapapeles. ¿Cómo copio una cadena en el portapapeles usando Python?
Creo que hay una solución mucho más simple para esto.
name = input(''What is your name? '')
print(''Hello %s'' % (name) )
Luego ejecuta tu programa en la línea de comando
python greeter.py | acortar
Esto canalizará la salida de su archivo al portapapeles
Esta es la forma más simple:
import pyperclip
pyperclip.copy("your string")
Si quieres obtener el contenido del portapapeles:
clipboard_content = pyperclip.paste()
Esta es la respuesta mejorada del atomizador .
Note 2 llamadas de update()
y 200 ms
retraso entre ellas. Protegen las aplicaciones de congelación debido a un estado inestable del portapapeles:
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()
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 en 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 .
He intentado 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 fuentes de línea Unix copiadas desde Windows. Los datos copiados permanecen en el portapapeles después de que Python sale: "Testing the “clip—board”: 📋"
Si no quiere dependencias externas, use este código (ahora parte de pyperclip
multiplataforma - 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
Los widgets también tienen un método llamado .clipboard_get()
que devuelve el contenido del portapapeles (a menos que ocurra algún tipo de error según el tipo de datos en el portapapeles).
El método clipboard_get()
se menciona en este informe de errores:
http://bugs.python.org/issue14777
Extrañamente, este método no fue mencionado en las fuentes de documentación en línea comunes (pero no oficiales) de TkInter a las que suelo hacer referencia.
No tenía una solución, solo una solución.
Windows Vista en adelante tiene un comando incorporado llamado clip
que toma el resultado de un comando desde la línea de comando y lo coloca en el portapapeles. Por ejemplo, ipconfig | clip
ipconfig | clip
.
Así que hice una función con el módulo os
que toma una cadena y la agrega al portapapeles usando la solución de Windows incorporada.
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 comando echo
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 en el Portapapeles .
Parece que necesita agregar win32clipboard a sus paquetes de sitio. Es parte del paquete pywin32
Por alguna razón, nunca pude lograr que la solución Tk me funcionara. 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 lidiar mejor con los caracteres Unicode extendidos y Python 3. Ha sido probado en Python 2.7 y 3.5, y funciona incluso con emoji como /U0001f601 (😁)
.
Puedes usar los pandas excelentes, que tienen un soporte incorporado en el portapapeles, pero necesitas pasar por un DataFrame.
import pandas as pd
df=pd.DataFrame([''Text to copy''])
df.to_clipboard(index=False,header=False)
También puede usar ctypes para acceder a la API de Windows y evitar el paquete masivo de pywin32. Esto es lo que uso (disculpe el estilo pobre, pero la idea está allí):
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()
puedes probar esto:
command = ''echo content |clip''
subprocess.check_call(command, shell=True)
En realidad, pywin32
y ctypes
parecen ser una exageración para esta simple tarea. Tkinter
es un marco de GUI multiplataforma, que viene 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 hay necesidad de perder el tiempo con bibliotecas de terceros específicas de la plataforma.
Si está utilizando Python 3, reemplace TKinter
por tkinter
.
from Tkinter import Tk
clip = Tk()
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)