Tôi đang cố gắng tạo một ứng dụng Windows cơ bản xây dựng một chuỗi từ đầu vào của người dùng và sau đó thêm nó vào bảng tạm. Làm cách nào để sao chép chuỗi vào bảng tạm bằng Python?
Tôi đang cố gắng tạo một ứng dụng Windows cơ bản xây dựng một chuỗi từ đầu vào của người dùng và sau đó thêm nó vào bảng tạm. Làm cách nào để sao chép chuỗi vào bảng tạm bằng Python?
Câu trả lời:
Trên thực tế, pywin32
và ctypes
dường như là một quá mức cho nhiệm vụ đơn giản này. Tkinter
là một khung GUI đa nền tảng, đi kèm với Python theo mặc định và có các phương thức truy cập clipboard cùng với các nội dung thú vị khác.
Nếu tất cả những gì bạn cần là đặt một số văn bản vào bảng tạm hệ thống, việc này sẽ thực hiện:
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()
Và đó là tất cả, không cần phải loay hoay với các thư viện bên thứ ba dành riêng cho nền tảng.
Nếu bạn đang sử dụng Python 3, hãy thay thế TKinter
bằng tkinter
.
r.destroy()
. Khi tôi gọi như vậy, bảng tạm sẽ trống và nhấn Ctrl-V có thể khiến ứng dụng đích bị đóng băng. (HĐH: Windows 7 x64)
Tôi không có giải pháp, chỉ là cách giải quyết.
Windows Vista trở đi có một lệnh inbuilt được gọi là clip
lấy đầu ra của lệnh từ dòng lệnh và đặt nó vào bảng tạm. Ví dụ , ipconfig | clip
.
Vì vậy, tôi đã tạo một hàm với os
mô-đun lấy một chuỗi và thêm nó vào bảng tạm bằng cách sử dụng giải pháp Windows sẵn có.
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.
Tuy nhiên, như đã lưu ý trong các bình luận, một nhược điểm của phương pháp này là echo
lệnh tự động thêm một dòng mới vào cuối văn bản của bạn. Để tránh điều này, bạn có thể sử dụng một phiên bản sửa đổi của lệnh:
def addToClipBoard(text):
command = 'echo | set /p nul=' + text.strip() + '| clip'
os.system(command)
Nếu bạn đang sử dụng Windows XP, nó sẽ hoạt động theo các bước trong Sao chép và dán từ dấu nhắc lệnh của Windows XP Pro thẳng vào Clipboard .
text
có chứa | calc.exe
?
text with " quotes and | pipe
trở thành "text with "" quotes and | pipe"
Mặc dù điều này có thể có vấn đề trên các hệ thống có cửa sổ cũ hơn 95.
type
. Tôi viết văn bản của tôi vào tập tin, và sử dụng lệnh type myfile.txt | clip
.
Bạn cũng có thể sử dụng ctypes để truy cập vào API Windows và tránh gói pywin32 lớn. Đây là những gì tôi sử dụng (xin lỗi phong cách nghèo nàn, nhưng ý tưởng là có):
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")
sang bytes(data)
. Cảm ơn bạn đã trả lời câu hỏi, tôi không thể sử dụng pywin32 hoặc tk hoặc một số thứ khác và điều này hoạt động.
bytes(data, "mbcs")
sẽ làm việc với mã hóa mặc định của windows. Cho phép tôi tải cái này vào clipboard "másreas ç saod é í ó u* ü ö ï/"
và đọc lại chính xác.
Bạn có thể sử dụng pyperclip - mô-đun clipboard đa nền tảng. Hoặc Xerox - mô-đun tương tự, ngoại trừ yêu cầu mô-đun win32 Python hoạt động trên Windows.
pyperclip
không làm Unicode trên Windows. win32clipboard
làm.
pyperclip
Bản vá của tôi đã được chấp nhận; c:\python34\Scripts\pip install --upgrade pyperclip
để xử lý văn bản Unicode.
pyperclip
, không phải paperclip
. Ngoài ra, như năm 2016, pyperclip cũng hoạt động với các ký tự Unicode. Tôi đã thử nghiệm các ký tự ± ° © đối với αåäö để hoạt động trên Win10 64-bit, với Python 3.5 và pyperclip 1.5.27.
Bạn có thể sử dụng những con gấu trúc tuyệt vời, có hỗ trợ trong bảng tạm, nhưng bạn cần phải vượt qua DataFrame.
import pandas as pd
df=pd.DataFrame(['Text to copy'])
df.to_clipboard(index=False,header=False)
pyperclip
dù sao thì nó cũng sử dụng , vì vậy sử dụng tốt hơnpyperpclip
pandas
có sẵn nhưng import pyperclip
không hoạt động. Vì vậy, tôi không đồng ý với "sử dụng pyperclip tốt hơn".
import pandas.io.clipboard as pyperclip
hoặc đặt tên cho nó bất cứ điều gì bạn muốn. Đó là nơi nó nằm trong pandas
, ít nhất là
Cách đơn giản nhất là với pyperclip . Hoạt động trong python 2 và 3.
Để cài đặt thư viện này, sử dụng:
pip install pyperclip
Ví dụ sử dụng:
import pyperclip
pyperclip.copy("your string")
Nếu bạn muốn lấy nội dung của bảng tạm:
clipboard_content = pyperclip.paste()
pyperclip
mô-đun có đi kèm với Python không? Phiên bản nào? Tôi không thấy nó trong Python 2.7 ...
pyperclip.paste()
không hoạt động với hình ảnh chỉ trả về NoneType
lỗi. nhưng hoạt động với nhấp chuột phải và sao chép sau đó sử dụng python để dán kết quả được sao chép.
Tôi đã thử nhiều giải pháp khác nhau, nhưng đây là giải pháp đơn giản nhất vượt qua bài kiểm tra của tôi :
#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'))
Đã kiểm tra OK trong Python 3.4 trên Windows 8.1 và Python 2.7 trên Windows 7. Ngoài ra khi đọc dữ liệu Unicode với các nguồn cấp dữ liệu Unix được sao chép từ Windows. Dữ liệu được sao chép vẫn còn trên bảng tạm sau khi Python thoát:"Testing
the “clip—board”: 📋"
Nếu bạn không muốn phụ thuộc bên ngoài, hãy sử dụng mã này (bây giờ là một phần của đa nền tảng 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
đâu Nó không phải là một phần của Python 2.7 của tôi. Và tại sao paste
sử dụng CF_TEXT
thay vì CF_UNICODETEXT
?
Vì một số lý do, tôi chưa bao giờ có thể khiến giải pháp Tk hoạt động cho mình. Giải pháp của kapace khả thi hơn nhiều, nhưng định dạng trái với phong cách của tôi và nó không hoạt động với Unicode. Đây là một phiên bản sửa đổi.
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
Ở trên đã thay đổi kể từ khi câu trả lời này được tạo lần đầu tiên, để đối phó tốt hơn với các ký tự Unicode mở rộng và Python 3. Nó đã được thử nghiệm trong cả Python 2.7 và 3.5 và hoạt động ngay cả với biểu tượng cảm xúc như \U0001f601 (😁)
.
put()
chức năng cũng cần làm việc; biểu tượng cảm xúc "" (\ U0001f400) được sao chép dưới dạng "" (\ U0001f4cb) hoặc "." chuyển sang "".
Có vẻ như bạn cần thêm win32clipboard vào các gói trang web của mình. Đây là một phần của gói pywin32
Bạn có thể sử dụng mô-đun clipboard
. Nó đơn giản và cực kỳ dễ sử dụng. Hoạt động với Mac , Windows và Linux .
Lưu ý: Đây là một thay thế củapyperclip
Sau khi cài đặt, nhập nó:
import clipboard
Sau đó, bạn có thể sao chép như thế này:
clipboard.copy("This is copied")
Bạn cũng có thể dán văn bản đã sao chép:
clipboard.paste()
pip install clipboard
.
Đây là cách dễ dàng và đáng tin cậy nhất mà tôi tìm thấy nếu bạn ổn tùy thuộc vào Pandas. Tuy nhiên tôi không nghĩ rằng đây chính thức là một phần của API Pandas nên nó có thể bị hỏng với các bản cập nhật trong tương lai. Nó hoạt động kể từ 0.25.3
from pandas.io.clipboard import copy
copy("test")
Widgets cũng có phương thức được đặt tên .clipboard_get()
trả về nội dung của clipboard (trừ khi một số loại lỗi xảy ra dựa trên loại dữ liệu trong clipboard).
Các clipboard_get()
phương pháp được đề cập trong báo cáo lỗi này:
http://bugs.python.org/issue14777
Thật kỳ lạ, phương pháp này không được đề cập trong các nguồn tài liệu TkInter trực tuyến phổ biến (nhưng không chính thức) mà tôi thường đề cập đến.
Tôi nghĩ rằng có một giải pháp đơn giản hơn nhiều cho việc này.
name = input('What is your name? ')
print('Hello %s' % (name) )
Sau đó chạy chương trình của bạn trong dòng lệnh
python helloer.py | kẹp
Điều này sẽ dẫn đầu ra của tập tin của bạn vào clipboard
Ngoài câu trả lời của Mark Ransom bằng cách sử dụng ctypes: Điều này không hoạt động đối với (tất cả?) X64 vì các tay cầm dường như bị cắt cụt thành kích thước int. Việc xác định rõ ràng các giá trị đối số và trả về giúp khắc phục vấn đề này.
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ạn mã tôi chia sẻ ở đây tận dụng khả năng định dạng tệp văn bản: nếu bạn muốn sao chép một đầu ra phức tạp vào bảng tạm thì sao? (Nói một mảng numpy trong cột hoặc danh sách một cái gì đó)
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
Tôi chỉ làm việc cho windows, có thể được điều chỉnh cho linux hoặc mac tôi đoán. Có lẽ hơi phức tạp ...
thí dụ:
>>>cp2clip(["ET","phone","home"])
>>>0
Ctrl + V trong bất kỳ trình soạn thảo văn bản nào:
ET
phone
home
Đây là câu trả lời cải tiến của phun .
Lưu ý 2 cuộc gọi update()
và 200 ms
trì hoãn giữa chúng. Chúng bảo vệ các ứng dụng đóng băng do trạng thái không ổn định của clipboard:
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()
Sử dụng thư viện clipboard của python!
import clipboard as cp
cp.copy("abc")
Clipboard chứa 'abc' bây giờ. Chúc mừng dán!
Không phải tất cả các câu trả lời đều hoạt động cho các cấu hình python khác nhau của tôi, vì vậy giải pháp này chỉ sử dụng mô đun quy trình con. Tuy nhiên, copy_keyword
phải pbcopy
dành cho Mac hoặc clip
cho Windows:
import subprocess
subprocess.run('copy_keyword', universal_newlines=True, input='New Clipboard Value 😀')
Đây là một số mã mở rộng hơn tự động kiểm tra hệ điều hành hiện tại là gì:
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)
Bạn có thể sử dụng mô-đun winclip32! Tải về:
pip install winclip32
sao chép:
import winclip32
winclip32.set_clipboard_data(winclip32.UNICODE_STD_TEXT, "some text")
để có được:
import winclip32
print(winclip32.get_clipboard_data(winclip32.UNICODE_STD_TEXT))
để biết thêm thông tin: https://pypi.org/project/winclip32/
Đoạn mã để sao chép bảng tạm:
Tạo một mã trình bao bọc Python trong một mô-đun có tên ( 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()
Sau đó nhập mô-đun trên vào mã của bạn.
import io
import clipboard
code = clipboard.getText()
print code
code = "abcd"
clipboard.setText(code)
Tôi phải cung cấp tín dụng cho bài đăng trên blog Truy cập Clipboard trong IronPython .
from Tkinter import Tk
clip = Tk()