Próbuję utworzyć podstawową aplikację systemu Windows, która buduje ciąg znaków na podstawie danych wprowadzonych przez użytkownika, a następnie dodaje go do schowka. Jak skopiować ciąg do schowka za pomocą Pythona?
Próbuję utworzyć podstawową aplikację systemu Windows, która buduje ciąg znaków na podstawie danych wprowadzonych przez użytkownika, a następnie dodaje go do schowka. Jak skopiować ciąg do schowka za pomocą Pythona?
Odpowiedzi:
Właściwie, pywin32
i ctypes
wydaje się być przesadą dla tego prostego zadania. Tkinter
to wieloplatformowy framework GUI, który jest domyślnie dostarczany z Pythonem i ma metody dostępu do schowka wraz z innymi fajnymi rzeczami.
Jeśli wystarczy wstawić tekst do schowka systemowego, zrobi to:
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()
I to wszystko, nie trzeba się bawić z bibliotekami stron trzecich specyficznymi dla platformy.
Jeśli używasz Python 3, wymienić TKinter
się tkinter
.
r.destroy()
. Po wywołaniu tego schowek staje się pusty, a naciśnięcie Ctrl-V może spowodować zawieszenie się aplikacji docelowej. (System operacyjny: Windows 7 x64)
Nie miałem rozwiązania, tylko obejście.
Windows Vista i nowsze mają wbudowane polecenie o nazwie, clip
które pobiera dane wyjściowe polecenia z wiersza poleceń i umieszcza je w schowku. Na przykład,ipconfig | clip
.
Zrobiłem więc funkcję z os
modułem, który pobiera ciąg znaków i dodaje go do schowka za pomocą wbudowanego rozwiązania 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.
Jednak, jak zauważono wcześniej w komentarzach, jednym minusem tego podejścia jest to, że echo
polecenie automatycznie dodaje nowy wiersz na końcu tekstu. Aby tego uniknąć, możesz użyć zmodyfikowanej wersji polecenia:
def addToClipBoard(text):
command = 'echo | set /p nul=' + text.strip() + '| clip'
os.system(command)
Jeśli korzystasz z systemu Windows XP, będzie on działać po prostu wykonując czynności opisane w sekcji Kopiuj i wklej z wiersza polecenia systemu Windows XP Pro bezpośrednio do schowka .
text
zawiera | calc.exe
?
text with " quotes and | pipe
staje się "text with "" quotes and | pipe"
Chociaż może to mieć problemy w systemach z Windows starszymi niż 95.
type
. Piszę tekst do pliku i używam polecenia type myfile.txt | clip
.
Możesz także użyć ctypes, aby skorzystać z Windows API i uniknąć ogromnego pakietu pywin32. Oto, czego używam (przepraszam za kiepski styl, ale pomysł już istnieje):
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")
na bytes(data)
. Dzięki za odpowiedź na pytanie, nie mogę użyć pywin32 lub tk lub kilku innych rzeczy i to działa.
bytes(data, "mbcs")
będzie działać z domyślnym kodowaniem systemu Windows. Pozwolił mi załadować to do schowka "másreas ç saod é í ó u* ü ö ï/"
i poprawnie odczytać.
Możesz użyć pyperclip - międzyplatformowego modułu schowka. Lub Xerox - podobny moduł, z tym wyjątkiem, że wymaga modułu Python win32 do pracy w systemie Windows.
pyperclip
nie robi Unicode w systemie Windows. win32clipboard
robi.
pyperclip
łatka została zaakceptowana; c:\python34\Scripts\pip install --upgrade pyperclip
do obsługi tekstu Unicode.
pyperclip
nie jest paperclip
. Podobnie jak w 2016 roku pyperclip działa również ze znakami Unicode. Testowałem znaki ± ° © © αβγθΔΨΦåäö do pracy na Win10 64-bit, z Python 3.5 i pyperclip 1.5.27.
Możesz użyć doskonałych pand, które mają wbudowaną obsługę schowka, ale musisz przejść przez ramkę danych.
import pandas as pd
df=pd.DataFrame(['Text to copy'])
df.to_clipboard(index=False,header=False)
pyperclip
tak używa , więc lepiej użyjpyperpclip
pandas
jest łatwo dostępny, ale import pyperclip
nie działa. Nie zgadzam się więc z „lepszym użyciem pyperclipa”.
import pandas.io.clipboard as pyperclip
lub nazwać go, jak chcesz. Tam pandas
przynajmniej się znajduje
Najprostszym sposobem jest użycie klipsa . Działa w Pythonie 2 i 3.
Aby zainstalować tę bibliotekę, użyj:
pip install pyperclip
Przykładowe użycie:
import pyperclip
pyperclip.copy("your string")
Jeśli chcesz uzyskać zawartość schowka:
clipboard_content = pyperclip.paste()
pyperclip
moduł jest dostarczany z Pythonem? Które wersje? Nie widzę tego w Pythonie 2.7 ...
pyperclip.paste()
nie działa z obrazami, po prostu zwraca NoneType
błąd. ale działa z kliknięciem prawym przyciskiem myszy i skopiowaniem, a następnie za pomocą Pythona wkleić skopiowane wyniki.
Próbowałem różnych rozwiązań, ale jest to najprostsze, które przechodzi mój 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'))
Testowano OK w Pythonie 3.4 w systemie Windows 8.1 i Pythonie 2.7 w systemie Windows 7. Również podczas odczytywania danych Unicode z uniksowymi liniami skopiowanymi z systemu Windows. Skopiowane dane pozostają w schowku po zamknięciu Pythona:"Testing
the “clip—board”: 📋"
Jeśli nie chcesz żadnych zewnętrznych zależności, użyj tego kodu (teraz stanowi część platformy 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
? To nie jest część mojego Pythona 2.7. I dlaczego paste
używa CF_TEXT
zamiast CF_UNICODETEXT
?
Z jakiegoś powodu nigdy nie udało mi się uzyskać rozwiązania Tk dla mnie. Rozwiązanie kapace jest o wiele bardziej praktyczne, ale formatowanie jest sprzeczne z moim stylem i nie działa z Unicode. Oto zmodyfikowana wersja.
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
Powyższe zmieniło się od czasu utworzenia tej odpowiedzi, aby lepiej radzić sobie z rozszerzonymi znakami Unicode i Pythonem 3. Został przetestowany zarówno w Pythonie 2.7, jak i 3.5, i działa nawet z emoji takimi jak \U0001f601 (😁)
.
put()
Funkcja wymaga również pracy; emoji „📋” (\ U0001f400) jest kopiowane jako „🐀” (\ U0001f4cb) lub „📋.” zmienia się w „📋”.
Wygląda na to, że musisz dodać win32clipboard do swoich pakietów witryn. Jest to część pakietu pywin32
Możesz użyć modułu clipboard
. Jest prosty i niezwykle łatwy w użyciu. Działa z komputerami Mac , Windows i Linux .
Uwaga: Jest to alternatywa dlapyperclip
Po zainstalowaniu zaimportuj:
import clipboard
Następnie możesz skopiować w następujący sposób:
clipboard.copy("This is copied")
Możesz również wkleić skopiowany tekst:
clipboard.paste()
pip install clipboard
.
Oto najłatwiejszy i najbardziej niezawodny sposób, jaki znalazłem, jeśli nie masz nic przeciwko Pandom. Jednak nie sądzę, że jest to oficjalnie część interfejsu API Pandas, więc może zepsuć się z przyszłymi aktualizacjami. Działa od 0.25.3
from pandas.io.clipboard import copy
copy("test")
Widżety mają także nazwaną metodę, .clipboard_get()
która zwraca zawartość schowka (chyba że wystąpi jakiś błąd w zależności od typu danych w schowku).
clipboard_get()
Metoda jest wymieniona w tym raportu o błędzie:
http://bugs.python.org/issue14777
O dziwo, ta metoda nie została wymieniona w typowych (ale nieoficjalnych) źródłach dokumentacji online TkInter, do których zwykle się odnoszę.
Myślę, że istnieje o wiele prostsze rozwiązanie tego problemu.
name = input('What is your name? ')
print('Hello %s' % (name) )
Następnie uruchom swój program w wierszu poleceń
python greeter.py | spinacz
Spowoduje to przesłanie pliku wyjściowego do schowka
Oprócz odpowiedzi Marka Ransoma przy użyciu ctypów: To nie działa w przypadku (wszystkich?) Systemów x64, ponieważ uchwyty wydają się być obcięte do rozmiaru wewnętrznego. Jawne definiowanie argumentów i zwracanych wartości pomaga przezwyciężyć ten problem.
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)
Fragment, który tu udostępniam, korzysta z możliwości formatowania plików tekstowych: co zrobić, jeśli chcesz skopiować złożone dane wyjściowe do schowka? (Powiedz tablicę numpy w kolumnie lub liście czegoś)
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
działa tylko w systemie Windows, myślę, że można go dostosować do systemu Linux lub Mac. Może trochę skomplikowane ...
przykład:
>>>cp2clip(["ET","phone","home"])
>>>0
Ctrl + V w dowolnym edytorze tekstu:
ET
phone
home
To jest ulepszona odpowiedź atomizera .
Uwaga 2 połączenia update()
i 200 ms
opóźnienia między nimi. Chronią aplikacje zamrażające z powodu niestabilnego stanu schowka:
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()
Użyj biblioteki schowka Pythona!
import clipboard as cp
cp.copy("abc")
Schowek zawiera teraz „abc”. Szczęśliwego wklejania!
Nie wszystkie odpowiedzi działały dla moich różnych konfiguracji Pythona, więc to rozwiązanie wykorzystuje tylko moduł podprocesu. Jednak copy_keyword
musi być pbcopy
na Mac lub clip
Windows:
import subprocess
subprocess.run('copy_keyword', universal_newlines=True, input='New Clipboard Value 😀')
Oto bardziej rozbudowany kod, który automatycznie sprawdza, jaki jest obecny system operacyjny:
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)
Możesz użyć modułu winclip32! zainstalować:
pip install winclip32
kopiować:
import winclip32
winclip32.set_clipboard_data(winclip32.UNICODE_STD_TEXT, "some text")
uzyskać:
import winclip32
print(winclip32.get_clipboard_data(winclip32.UNICODE_STD_TEXT))
Więcej informacji: https://pypi.org/project/winclip32/
Fragment kodu, aby skopiować schowek:
Utwórz otoki kod Pythona w module o nazwie ( 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()
Następnie zaimportuj powyższy moduł do swojego kodu.
import io
import clipboard
code = clipboard.getText()
print code
code = "abcd"
clipboard.setText(code)
Muszę wyrazić uznanie dla wpisu na blogu Dostęp do schowka w IronPython .
from Tkinter import Tk
clip = Tk()