如何使用Python将字符串复制到Windows上的剪贴板?

tes*_*ter 170 python clipboard

我正在尝试创建一个基本的Windows应用程序,用户输入构建一个字符串,然后将其添加到剪贴板.如何使用Python将字符串复制到剪贴板?

ato*_*zer 260

其实,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()
Run Code Online (Sandbox Code Playgroud)

这就是全部,不需要使用特定于平台的第三方库.

如果您使用的是Python 3,请替换TKintertkinter.

  • 获取剪贴板的内容:result = r.selection_get(selection ="CLIPBOARD") (51认同)
  • @SurDin Tkinter在python 3中被重命名为tkinter,所以它取决于你使用的是什么版本. (31认同)
  • 使用此功能粘贴剪贴板的内容后,我的所有应用都无法响应,奇怪的是,获得的结果正常. (23认同)
  • 如果我不调用`r.destroy()`它就可以工作.一旦我调用它,剪贴板就会变空,按Ctrl-V可能会导致目标应用程序冻结.(操作系统:Windows 7 x64) (14认同)
  • 这是一个很好的例子,一个非常旧的过时的答案紧贴在顶部,而你必须向下滚动,查看“已回答”的日期才能找到“当前”的最佳方法。 (12认同)
  • 对我来说,这对python 3.4不起作用,但它适用于python 2.7(是的,使用tkinter而不是Tkinter) (8认同)
  • 获取剪贴板的内容:`r.clipboard_get()` (5认同)
  • @BartlomiejLewandowski据我所知tkinter在你在python中循环任何东西时不会释放剪贴板. (3认同)
  • 如果在控制台脚本中使用它,这可能会导致错误,.destroy()函数将无法工作("无法调用"事件"命令:应用程序在执行[...]时已被销毁").为了防止这种情况,请在`r.destroy`之前调用`r.update()`. (3认同)
  • @kapace:[Python中的相关错误](http://bugs.python.org/issue14777).现在修好了. (2认同)
  • 在IDLE中使用Python 2.7.2对我来说根本不起作用。@Kiwi发布的r.clipboard_get()将其打印到IDLE Python shell中,但在其他应用程序中不可用(尝试发布到记事本等)。 (2认同)
  • 这适用于Linux/python 2.7.6在交互式控制台中,但不适用于脚本!?我尝试了几次测试,无法理解为什么...... (2认同)
  • 在Spyder中,这只适用于Python控制台,但不适用于i-Python控制台. (2认同)
  • ctypes(围绕低级Win32 API的简约包装器)过大,因此人们应该使用* TK *?这个答案非常非常困惑... (2认同)

小智 75

我没有解决方案,只是一种解决方法.

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.
Run Code Online (Sandbox Code Playgroud)

然而,正如之前在评论中所指出的,这种方法的一个缺点是该echo命令会自动在文本末尾添加换行符.要避免这种情况,您可以使用命令的修改版本:

def addToClipBoard(text):
    command = 'echo | set /p nul=' + text.strip() + '| clip'
    os.system(command)
Run Code Online (Sandbox Code Playgroud)

如果您使用的是Windows XP,它将按照从Windows XP Pro的命令提示符中直接复制并粘贴到剪贴板中的步骤进行操作.

  • 如果`text`包含`|会发生什么 calc.exe`? (20认同)
  • 非常不安全的功能...发送到剪贴板的内容现在是一个入口向量,因此会增加你的攻击面. (5认同)
  • @WilliBallenthin然后你需要用双引号括起来.但如果它包含双引号怎么办?然后你需要加倍双引号.带有"引号和|管道"的文本变为"带有""引号和"的文本 管道"`虽然这可能在Windows早于95的系统上出现问题. (2认同)
  • 我还需要支持换行符,所以我修改了它以使用`type`.我将文本写入文件,并使用命令`type myfile.txt | clip`. (2认同)

kap*_*ace 39

您还可以使用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()
Run Code Online (Sandbox Code Playgroud)

  • 至少在python 2.6 x64中,我不得不将`bytes(data,"ascii")`更改为`bytes(data)`.感谢您回答这个问题,我不能使用pywin32或tk或其他一些东西,这是有效的. (4认同)
  • 使用 mbcs 给我这个: OSError: 异常: 访问冲突写入 0x0000000000000000 (2认同)

pon*_*ngo 30

您可以使用pyperclip - 跨平台剪贴板模块.或者Xerox - 类似的模块,除了要求win32 Python模块在Windows上运行.

  • 我的'pyperclip`补丁被接受了; `c:\ python34\Scripts\pip install --upgrade pyperclip`来处理Unicode文本. (11认同)
  • 我花了一段时间才发现这是“pyperclip”,而不是“paperclip”。此外,与 2016 年一样,pyperclip 也可以使用 Unicode 字符。我已经使用 Python 3.5 和 pyperclip 1.5.27 测试了字符 ±°©αβγθΔΨΦåäö 在 Win10 64 位上的工作情况。 (2认同)

小智 25

您可以使用优秀的pandas,它具有内置的剪贴板支持,但您需要通过DataFrame.

import pandas as pd
df=pd.DataFrame(['Text to copy'])
df.to_clipboard(index=False,header=False)
Run Code Online (Sandbox Code Playgroud)

  • 无论如何这都使用`pyperclip`,所以最好使用`pyperpclip` (4认同)
  • 如果您仅限于使用 pandas,则可以通过“import pandas.io.clipboard as pyperclip”直接使用 pyperclip 或将其命名为您想要的任何名称。至少这就是它位于“pandas”中的位置 (3认同)
  • +1。我喜欢这个解决方案。它比公认的Tkinter解决方案还要简单。无论如何,如果您导入了大熊猫,就不会有额外的开销。它还适用于所有平台。在大多数情况下,它甚至不需要安装新的软件包。 (2认同)
  • 对于大多数人(即我)来说,`pandas` 很容易获得,但 `import pyperclip` 不起作用。所以我不同意“更好地使用 pyperclip”。 (2认同)
  • 如果您已经加载了“pandas”并且不想保留数据框,则可以将其简化为一行:“pd.DataFrame(['要复制的文本']).to_clipboard(excel=False,index= False,header=False)` excel=False 参数删除 @GijvanOort 评论中提到的换行符 (2认同)

Eso*_*ack 16

这是我找到的最简单可靠的方法,如果你没问题,取决于 Pandas。但是我认为这不是 Pandas API 的正式组成部分,因此它可能会随着未来的更新而中断。它从 0.25.3 开始工作

from pandas.io import clipboard
clipboard.copy("test")
Run Code Online (Sandbox Code Playgroud)

  • 这只是 Pyperclip 的包装!(或者更准确地说...... pandas 只是将一些 pyperclip 版本的副本放入其 src 中) (4认同)
  • 对我有用,但我可能会使用“from pandas.io import Clipboard”,然后使用“clipboard.copy(...)”以避免与其他“copy”方法混淆。 (2认同)

mav*_*viz 14

最简单的方法是使用pyperclip.适用于python 2和3.

要安装此库,请使用:

pip install pyperclip
Run Code Online (Sandbox Code Playgroud)

用法示例:

import pyperclip

pyperclip.copy("your string")
Run Code Online (Sandbox Code Playgroud)

如果要获取剪贴板的内容:

clipboard_content = pyperclip.paste()
Run Code Online (Sandbox Code Playgroud)

  • 是的,低估了一个答案,可以在不到5行中轻松解决问题; 因为像参考这样的细节更重要; stackoverflow的好用途我的朋友.无论如何我会为nitpickers编辑.给你的提示:downvote无用或无法解决问题的答案; upvote答案解决问题或至少是有用的,并在评论中提出建议,以改善有用的答案,而不是downvoting. (6认同)
  • `pyperclip`模块是否附带Python?哪个版本?我在Python 2.7中没有看到它...... (3认同)
  • 没有参考,您什么都解决不了。但是自从您添加了链接以来,由于现在的答案很好,因此我将删除downvote。我更大的问题是,它看起来像是标准库的导入。它看起来像可以复制/粘贴的代码。 (2认同)
  • @JayRizzo 这个问题没有询问有关将图像复制到剪贴板的问题。但是,您可以使用 Pillow 库的 ImageGrab.grabclipboard() 模块 (pip install Pillow)。 (2认同)

Ali*_*jad 12

使用pyperclip模块

使用 pip 安装pip install pyperclip

将文本复制"Hello World!"到剪贴板

import pyperclip
pyperclip.copy('Hello World!')
Run Code Online (Sandbox Code Playgroud)

您可以使用Ctrl+V任何地方将其粘贴到某处。

使用 python 粘贴复制的文本

pyperclip.paste() # This returns the copied text of type <class 'str'>
Run Code Online (Sandbox Code Playgroud)


Jas*_*oon 10

看起来您需要将win32clipboard添加到您的站点包中.它是pywin32包的一部分

  • 如果有一些示例代码,将会是一个更好的答案。 (3认同)

Mar*_*som 10

出于某种原因,我从来没有能够让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
Run Code Online (Sandbox Code Playgroud)

自从这个答案首次创建以来,上面已经改变,以更好地处理扩展的Unicode字符和Python 3.它已经在Python 2.7和3.5中进行了测试,甚至可以用于表情符号,例如\U0001f601 ().


Fet*_*or7 10

并非所有答案都适用于我的各种 python 配置,因此该解决方案仅使用 subprocess 模块。但是,copy_keyword必须适用pbcopy于 Mac 或clipWindows:

import subprocess
subprocess.run('copy_keyword', universal_newlines=True, input='New Clipboard Value ')
Run Code Online (Sandbox Code Playgroud)

下面是一些更广泛的代码,可以自动检查当前操作系统是什么:

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)
Run Code Online (Sandbox Code Playgroud)


Cee*_*man 9

我已经尝试了各种解决方案,但是这是通过最简单的一个我的测试:

#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'))
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)


Bla*_*der 8

您可以使用模块clipboard。它简单易用。适用于MacWindowsLinux
注意:它的替代品pyperclip

安装后,导入:

import clipboard
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样复制:

clipboard.copy("This is copied")
Run Code Online (Sandbox Code Playgroud)

您还可以粘贴复制的文本:

clipboard.paste()
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是最好的解决方案。可以使用“pip install Clipboard”安装剪贴板。 (2认同)
  • `clipboard` 包只是 `pyperclip` 包的无耻复制。正如其代码所示[此处](https://github.com/terryyin/clipboard/blob/master/clipboard.py)。 (2认同)

小智 5

我认为对此有一个更简单的解决方案。

name = input('What is your name? ')
print('Hello %s' % (name) )
Run Code Online (Sandbox Code Playgroud)

然后在命令行中运行你的程序

python 问候语.py | 夹子

这会将文件的输出通过管道传输到剪贴板