如何使用Python将字符串复制到Windows上的剪贴板?
我试图做一个基本的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
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.
如果您使用的是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上工作。
看起来你需要添加win32clipboard到你的网站包。 它是pywin32包的一部分
你可以使用优秀的熊猫,它有一个内置的剪贴板支持,但你需要通过一个数据帧。
import pandas as pd df=pd.DataFrame(['Text to copy']) df.to_clipboard(index=False,header=False)
我尝试了各种解决方案,但是这是通过我的测试的最简单的方法:
#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,测试结果也一样。 Python退出后,复制的数据保留在剪贴板上: "Testing the “clip—board”: 📋"
剪贴板"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
出于某种原因,我从来没有能够得到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 (😁)
等表情符号。
我认为有一个更简单的解决方案。
name = input('What is your name? ') print('Hello %s' % (name) )
然后在命令行中运行你的程序
python greeter.py | 夹
这会将您的文件的输出传送到剪贴板
小部件也有名为.clipboard_get()
方法,它返回剪贴板的内容(除非根据剪贴板中的数据类型发生某种错误)。
这个bug报告中提到了clipboard_get()
方法:
http://bugs.python.org/issue14777
奇怪的是,这种方法在我通常提到的常见(但非官方)的在线TkInter文档中没有提到。
这是最简单的方法:
import pyperclip pyperclip.copy("your string")
如果你想获得剪贴板的内容:
clipboard_content = pyperclip.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)
这是雾化器的改进的答案。
注2: update()
和它们之间的延迟时间为200 ms
。 由于剪贴板的状态不稳定,它们可以保护冷冻应用程序:
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()
代码片段复制剪贴板:
在名为( clipboard.py )的模块中创建封装Python代码:
import clr clr.AddReference('System.Windows.Forms') from System.Windows.Forms import Clipboard def setText(text): Clipboard.SetText(text) def getText(): return Clipboard.GetText()
然后将上面的模块导入到您的代码中。
import io import clipboard code = clipboard.getText() print code code = "abcd" clipboard.setText(code)
我必须赞扬IronPython中的博客帖子剪贴板访问 。
from Tkinter import Tk clip = Tk()