我正在尝试创建一个基本的Windows应用程序,用户输入构建一个字符串,然后将其添加到剪贴板.如何使用Python将字符串复制到剪贴板?
其实,pywin32
并且ctypes
似乎是这个简单的任务矫枉过正.Tkinter
是一个跨平台的GUI框架,默认情况下附带Python,并具有剪贴板访问方法以及其他很酷的东西.
如果只需要将一些文本放到系统剪贴板中,这样就可以了:
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()
这就是全部,不需要使用特定于平台的第三方库.
如果您使用的是Python 3,请替换TKinter
为tkinter
.
我没有解决方案,只是一种解决方法.
Windows Vista以后有一个内置的命令clip
,它从命令行获取命令的输出并将其放入剪贴板.例如,ipconfig | clip
.
所以我用os
模块创建了一个函数,它接受一个字符串并使用内置的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.
然而,正如之前在评论中所指出的,这种方法的一个缺点是该echo
命令会自动在文本末尾添加换行符.要避免这种情况,您可以使用命令的修改版本:
def addToClipBoard(text): command = 'echo | set /p nul=' + text.strip() + '| clip' os.system(command)
如果您使用的是Windows XP,它将按照从Windows XP Pro的命令提示符中直接复制并粘贴到剪贴板中的步骤进行操作.
您还可以使用ctypes进入Windows API并避免使用庞大的pywin32软件包.这就是我使用的(原谅可怜的风格,但想法就在那里):
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()
您可以使用pyperclip - 跨平台剪贴板模块.或者Xerox - 类似的模块,除了要求win32 Python模块在Windows上运行.
您可以使用优秀的pandas,它具有内置的剪贴板支持,但您需要通过DataFrame.
import pandas as pd df=pd.DataFrame(['Text to copy']) df.to_clipboard(index=False,header=False)
最简单的方法是使用pyperclip.适用于python 2和3.
要安装此库,请使用:
pip install pyperclip
用法示例:
import pyperclip pyperclip.copy("your string")
如果要获取剪贴板的内容:
clipboard_content = pyperclip.paste()
看起来您需要将win32clipboard添加到您的站点包中.它是pywin32包的一部分
出于某种原因,我从来没有能够让Tk解决方案为我工作.kapace的解决方案更加可行,但格式化与我的风格相反,并且它不适用于Unicode.这是一个修改过的版本.
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
自从这个答案首次创建以来,上面已经改变,以更好地处理扩展的Unicode字符和Python 3.它已经在Python 2.7和3.5中进行了测试,甚至可以用于表情符号,例如\U0001f601 ()
.
我已经尝试了各种解决方案,但是这是通过最简单的一个我的测试:
#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'))
在Windows 8.1上的Python 3.4和Windows 7上的Python 2.7中测试OK.当从Windows复制的Unix换行中读取Unicode数据时也是如此.Python退出后复制的数据保留在剪贴板上:"Testing
the “clip—board”: "
如果您不想要外部依赖项,请使用此代码(现在是跨平台的一部分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