J'essaie de créer une application Windows de base qui crée une chaîne à partir de l'entrée utilisateur, puis l'ajoute au presse-papiers. Comment copier une chaîne dans le presse-papiers en utilisant Python?
J'essaie de créer une application Windows de base qui crée une chaîne à partir de l'entrée utilisateur, puis l'ajoute au presse-papiers. Comment copier une chaîne dans le presse-papiers en utilisant Python?
Réponses:
En fait, pywin32
et ctypes
semblent exagérés pour cette tâche simple. Tkinter
est un framework d'interface graphique multiplateforme, livré avec Python par défaut et doté de méthodes d'accès au presse-papiers ainsi que d'autres choses intéressantes.
Si tout ce dont vous avez besoin est de mettre du texte dans le presse-papiers du système, cela le fera:
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()
Et c'est tout, pas besoin de jouer avec les bibliothèques tierces spécifiques à la plate-forme.
Si vous utilisez Python 3, remplacez-le TKinter
par tkinter
.
r.destroy()
. Une fois que j'appelle cela, le presse-papiers devient vide et appuyer sur Ctrl-V peut provoquer le gel de l'application cible. (OS: Windows 7 x64)
Je n'avais pas de solution, juste une solution de contournement.
Windows Vista a une commande intégrée appelée clip
qui prend la sortie d'une commande à partir de la ligne de commande et la place dans le presse-papiers. Par exemple,ipconfig | clip
,.
J'ai donc créé une fonction avec le os
module qui prend une chaîne et l'ajoute au presse-papiers en utilisant la solution Windows intégrée.
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.
Cependant, comme indiqué précédemment dans les commentaires, un inconvénient de cette approche est que la echo
commande ajoute automatiquement une nouvelle ligne à la fin de votre texte. Pour éviter cela, vous pouvez utiliser une version modifiée de la commande:
def addToClipBoard(text):
command = 'echo | set /p nul=' + text.strip() + '| clip'
os.system(command)
Si vous utilisez Windows XP, il fonctionnera simplement en suivant les étapes de Copier et coller à partir de l'invite de commande de Windows XP Pro directement dans le Presse-papiers .
text
contient | calc.exe
?
text with " quotes and | pipe
devient "text with "" quotes and | pipe"
Bien que cela puisse avoir des problèmes sur les systèmes avec des fenêtres antérieures à 95.
type
. J'écris mon texte dans un fichier et j'utilise la commande type myfile.txt | clip
.
Vous pouvez également utiliser des ctypes pour accéder à l'API Windows et éviter le package pywin32 massif. C'est ce que j'utilise (excusez le style médiocre, mais l'idée est là):
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)
. Merci d'avoir répondu à la question, je ne peux pas utiliser pywin32 ou tk ou un certain nombre d'autres choses et cela fonctionne.
bytes(data, "mbcs")
fonctionnera avec l'encodage par défaut de Windows. M'a permis de charger ceci dans le presse-papiers "másreas ç saod é í ó u* ü ö ï/"
et de le relire correctement.
Vous pouvez utiliser pyperclip - module de presse-papiers multiplateforme. Ou Xerox - module similaire, sauf nécessite le module win32 Python pour fonctionner sous Windows.
pyperclip
ne fait pas Unicode sous Windows. win32clipboard
Est-ce que.
pyperclip
patch a été accepté; c:\python34\Scripts\pip install --upgrade pyperclip
pour gérer le texte Unicode.
pyperclip
pas le cas paperclip
. De plus, comme en 2016, pyperclip fonctionne également avec les caractères Unicode. J'ai testé des caractères ± ° © © αβγθΔΨΦåäö pour travailler sur Win10 64 bits, avec Python 3.5 et pyperclip 1.5.27.
Vous pouvez utiliser les excellents pandas, qui ont un support de presse-papiers intégré, mais vous devez passer par un DataFrame.
import pandas as pd
df=pd.DataFrame(['Text to copy'])
df.to_clipboard(index=False,header=False)
pyperclip
quand même, donc mieux utiliserpyperpclip
pandas
est facilement disponible mais import pyperclip
ne fonctionne pas. Donc je ne suis pas d'accord avec "mieux utiliser pyperclip".
import pandas.io.clipboard as pyperclip
ou le nommer comme vous le souhaitez. C'est là que ça se trouve pandas
, au moins
Le moyen le plus simple est avec pyperclip . Fonctionne en python 2 et 3.
Pour installer cette bibliothèque, utilisez:
pip install pyperclip
Exemple d'utilisation:
import pyperclip
pyperclip.copy("your string")
Si vous souhaitez obtenir le contenu du presse-papiers:
clipboard_content = pyperclip.paste()
pyperclip
module est-il livré avec Python? Quelles versions? Je ne le vois pas dans Python 2.7 ...
pyperclip.paste()
ne fonctionne pas avec les images renvoie juste une NoneType
erreur. mais fonctionne avec un clic droit et copiez puis en utilisant python pour coller les résultats copiés.
J'ai essayé différentes solutions, mais c'est la plus simple qui passe mon test :
#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'))
Testé OK dans Python 3.4 sur Windows 8.1 et Python 2.7 sur Windows 7. Également lors de la lecture de données Unicode avec des sauts de ligne Unix copiés à partir de Windows. Les données copiées restent dans le presse-papiers après la fermeture de Python:"Testing
the “clip—board”: 📋"
Si vous ne voulez pas de dépendances externes, utilisez ce code (qui fait maintenant partie de multiplateforme 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
? Cela ne fait pas partie de mon Python 2.7. Et pourquoi paste
utiliser CF_TEXT
au lieu de CF_UNICODETEXT
?
Pour une raison quelconque, je n'ai jamais réussi à faire fonctionner la solution Tk. La solution de kapace est beaucoup plus pratique, mais le formatage est contraire à mon style et ne fonctionne pas avec Unicode. Voici une version modifiée.
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
Ce qui précède a changé depuis la création de cette réponse, pour mieux gérer les caractères Unicode étendus et Python 3. Il a été testé en Python 2.7 et 3.5 et fonctionne même avec des emoji tels que \U0001f601 (😁)
.
put()
fonction a également besoin de travail; l'emoji "📋" (\ U0001f400) est copié en tant que "🐀" (\ U0001f4cb) ou "📋". se transforme en "📋".
Il semble que vous deviez ajouter win32clipboard à vos packages de site. Cela fait partie du package pywin32
Voici le moyen le plus simple et le plus fiable que j'ai trouvé si vous êtes d'accord avec les pandas. Cependant, je ne pense pas que cela fasse officiellement partie de l'API Pandas, donc cela pourrait rompre avec les futures mises à jour. Cela fonctionne à partir de 0.25.3
from pandas.io.clipboard import copy
copy("test")
Vous pouvez utiliser module clipboard
. C'est simple et extrêmement facile à utiliser. Fonctionne avec Mac , Windows et Linux .
Remarque: c'est une alternative depyperclip
Après l'installation, importez-le:
import clipboard
Ensuite, vous pouvez copier comme ceci:
clipboard.copy("This is copied")
Vous pouvez également coller le texte copié:
clipboard.paste()
pip install clipboard
.
Les widgets ont également une méthode nommée .clipboard_get()
qui renvoie le contenu du presse-papiers (à moins qu'une erreur ne se produise en fonction du type de données dans le presse-papiers).
La clipboard_get()
méthode est mentionnée dans ce rapport de bogue:
http://bugs.python.org/issue14777
Étrangement, cette méthode n'a pas été mentionnée dans les sources de documentation en ligne courantes (mais non officielles) de TkInter auxquelles je me réfère habituellement.
Je pense qu'il existe une solution beaucoup plus simple à cela.
name = input('What is your name? ')
print('Hello %s' % (name) )
Ensuite, exécutez votre programme dans la ligne de commande
python greeter.py | agrafe
Cela dirigera la sortie de votre fichier vers le presse-papiers
En plus de la réponse de Mark Ransom utilisant des ctypes: cela ne fonctionne pas pour (tous?) Les systèmes x64 car les poignées semblent être tronquées à la taille int. La définition explicite des arguments et des valeurs de retour permet de surmonter ce problème.
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)
L'extrait que je partage ici tire parti de la possibilité de formater des fichiers texte: que faire si vous souhaitez copier une sortie complexe dans le presse-papiers? (Dites un tableau numpy dans la colonne ou une liste de quelque chose)
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
fonctionne uniquement pour Windows, peut être adapté pour Linux ou Mac, je suppose. Peut-être un peu compliqué ...
exemple:
>>>cp2clip(["ET","phone","home"])
>>>0
Ctrl + V dans n'importe quel éditeur de texte:
ET
phone
home
C'est la réponse améliorée de l' atomiseur .
Notez 2 appels update()
et 200 ms
délai entre eux. Ils protègent les applications de congélation en raison d'un état instable du presse-papiers:
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()
Utilisez la bibliothèque de presse-papiers de python!
import clipboard as cp
cp.copy("abc")
Le presse-papiers contient maintenant «abc». Bon collage!
Toutes les réponses n'ont pas fonctionné pour mes différentes configurations python, donc cette solution utilise uniquement le module de sous-processus. Cependant, copy_keyword
doit être pbcopy
pour Mac ou clip
pour Windows:
import subprocess
subprocess.run('copy_keyword', universal_newlines=True, input='New Clipboard Value 😀')
Voici un code plus complet qui vérifie automatiquement quel est le système d'exploitation actuel:
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)
Vous pouvez utiliser le module winclip32! installer:
pip install winclip32
copier:
import winclip32
winclip32.set_clipboard_data(winclip32.UNICODE_STD_TEXT, "some text")
obtenir:
import winclip32
print(winclip32.get_clipboard_data(winclip32.UNICODE_STD_TEXT))
pour plus d'informations: https://pypi.org/project/winclip32/
Extrait de code pour copier le presse-papiers:
Créez un code Python wrapper dans un module nommé ( 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()
Importez ensuite le module ci-dessus dans votre code.
import io
import clipboard
code = clipboard.getText()
print code
code = "abcd"
clipboard.setText(code)
Je dois donner du crédit au billet de blog Clipboard Access en IronPython .
from Tkinter import Tk
clip = Tk()