232

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

4

26 回答 26

337

实际上,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,请替换TKintertkinter.

于 2010-11-17T11:31:06.507 回答
92

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

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 的命令提示符直接复制并粘贴到剪贴板中的步骤操作即可。

于 2012-02-23T09:06:00.927 回答
48

您可以使用pyperclip - 跨平台剪贴板模块。或Xerox - 类似的模块,但需要 win32 Python 模块才能在 Windows 上运行。

于 2014-07-02T05:43:27.550 回答
43

您还可以使用 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()
于 2010-08-07T03:33:26.060 回答
36

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

import pandas as pd
df=pd.DataFrame(['Text to copy'])
df.to_clipboard(index=False,header=False)
于 2016-03-23T12:36:54.027 回答
33

最简单的方法是使用pyperclip。在 python 2 和 3 中工作。

要安装此库,请使用:

pip install pyperclip

示例用法:

import pyperclip

pyperclip.copy("your string")

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

clipboard_content = pyperclip.paste()
于 2017-03-08T12:21:13.290 回答
22

如果您可以依赖 Pandas,这是我发现的最简单可靠的方法。但是我不认为这正式成为 Pandas API 的一部分,因此它可能会随着未来的更新而中断。它从 0.25.3 开始工作

from pandas.io import clipboard
clipboard.copy("test")
于 2019-11-23T20:45:13.867 回答
11

出于某种原因,我一直无法让 Tk 解决方案为我工作。kapace 的解决方案更可行,但格式与我的风格相反,它不适用于 Unicode。这是一个修改后的版本。

import ctypes

from ctypes.wintypes import BOOL, HWND, HANDLE, HGLOBAL, UINT, LPVOID
from ctypes import c_size_t as SIZE_T

OpenClipboard = ctypes.windll.user32.OpenClipboard
OpenClipboard.argtypes = HWND,
OpenClipboard.restype = BOOL
EmptyClipboard = ctypes.windll.user32.EmptyClipboard
EmptyClipboard.restype = BOOL
GetClipboardData = ctypes.windll.user32.GetClipboardData
GetClipboardData.argtypes = UINT,
GetClipboardData.restype = HANDLE
SetClipboardData = ctypes.windll.user32.SetClipboardData
SetClipboardData.argtypes = UINT, HANDLE
SetClipboardData.restype = HANDLE
CloseClipboard = ctypes.windll.user32.CloseClipboard
CloseClipboard.restype = BOOL
CF_UNICODETEXT = 13

GlobalAlloc = ctypes.windll.kernel32.GlobalAlloc
GlobalAlloc.argtypes = UINT, SIZE_T
GlobalAlloc.restype = HGLOBAL
GlobalLock = ctypes.windll.kernel32.GlobalLock
GlobalLock.argtypes = HGLOBAL,
GlobalLock.restype = LPVOID
GlobalUnlock = ctypes.windll.kernel32.GlobalUnlock
GlobalUnlock.argtypes = HGLOBAL,
GlobalSize = ctypes.windll.kernel32.GlobalSize
GlobalSize.argtypes = HGLOBAL,
GlobalSize.restype = SIZE_T

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 ().

2021-10-26 更新:这在 Windows 7 和 Python 3.8 中对我来说非常有用。然后我得到了一台装有 Windows 10 和 Python 3.10 的新计算机,它以与评论中所示相同的方式失败了。 这个帖子给了我答案。来自的函数ctypes没有正确指定参数和返回类型,并且默认值与 64 位值不一致。我已经修改了上面的代码以包含缺失的信息。

于 2014-09-05T03:11:03.157 回答
11

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

#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 中测试正常。在使用从 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
于 2014-12-04T10:20:38.780 回答
9

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

于 2009-02-23T22:43:08.647 回答
9

如果你不喜欢这个名字,你可以使用派生模块clipboard

注意:它只是一个选择性的包装器pyperclip

安装后,导入:

import clipboard

然后你可以像这样复制:

clipboard.copy("This is copied")

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

clipboard.paste()
于 2019-08-25T10:35:58.050 回答
6

使用pyperclip模块

使用 pip 安装pip install pyperclip

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

import pyperclip
pyperclip.copy('Hello World!')

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

使用python粘贴复制的文本

pyperclip.paste() # This returns the copied text of type <class 'str'>
于 2021-03-23T10:57:56.577 回答
3

小部件还有一个名为.clipboard_get()返回剪贴板内容的方法(除非根据剪贴板中的数据类型发生某种错误)。

clipboard_get()错误报告中提到了该方法:http:
//bugs.python.org/issue14777

奇怪的是,我通常参考的常见(但非官方)在线 TkInter 文档资源中没有提到这种方法。

于 2013-10-26T04:00:27.160 回答
3

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

name = input('What is your name? ')
print('Hello %s' % (name) )

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

蟒蛇欢迎者.py | 夹子

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

于 2017-01-23T20:42:19.467 回答
3

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

import subprocess
subprocess.run('copy_keyword', universal_newlines=True, input='New Clipboard Value ')

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

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)
于 2020-02-17T20:53:31.443 回答
1

除了Mark Ransom使用 ctypes 的回答:这不适用于(所有?)x64 系统,因为句柄似乎被截断为 int 大小。显式定义参数和返回值有助于克服这个问题。

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())
于 2019-09-24T10:34:55.110 回答
1

使用 python 的剪贴板库!

import clipboard as cp
cp.copy("abc")

剪贴板现在包含“abc”。快乐粘贴!

于 2019-12-16T12:20:53.250 回答
1

你也可以使用 >clipboard

import clipboard

def copy(txt):
    clipboard.copy(txt)
    
copy("your txt")
于 2021-08-16T07:41:13.500 回答
0
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)
于 2015-04-14T16:41:37.057 回答
0

这是雾化器的改进答案。

注意它们之间的 2 个调用update()200 ms延迟。由于剪贴板状态不稳定,它们可以保护冻结的应用程序:

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()
于 2017-02-18T23:13:47.243 回答
0

我在这里分享的片段利用了格式化文本文件的能力:如果你想将复杂的输出复制到剪贴板怎么办?(在列中说一个 numpy 数组或某个东西的列表)

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

仅适用于 Windows,我猜可以适用于 linux 或 mac。可能有点复杂...

例子:

>>>cp2clip(["ET","phone","home"])
>>>0

任何文本编辑器中的 Ctrl+V :

ET
phone
home
于 2019-04-10T11:23:10.287 回答
0

你可以使用winclip32模块!安装:

pip install winclip32

复印:

import winclip32
winclip32.set_clipboard_data(winclip32.UNICODE_STD_TEXT, "some text")

要得到:

import winclip32
print(winclip32.get_clipboard_data(winclip32.UNICODE_STD_TEXT))

更多信息:https ://pypi.org/project/winclip32/

于 2020-03-09T20:00:53.187 回答
0

在 Windows 上,您可以使用它。没有外部依赖也不必打开子流程:

import win32clipboard


def to_clipboard(txt):

    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardText(txt)
    win32clipboard.CloseClipboard()
于 2021-07-28T15:29:22.403 回答
0

如果(且仅当)应用程序已经使用 Qt,您可以使用它(优点是没有额外的第三方依赖)

from PyQt5.QtWidgets import QApplication
clipboard = QApplication.clipboard()

# get text (if there's text inside instead of e.g. file)
clipboard.text()

# set text
clipboard.setText(s)

这要求已经构造了一个 Qt 应用程序对象,因此除非应用程序已经使用 Qt,否则不应使用它。

此外,像往常一样,在 X 系统(可能还有其他系统)中,除非您使用 parcellite 或 xclipboard 之类的东西,否则内容只会持续到应用程序存在为止。

文档:

另请参阅:python - PyQT - 将文件复制到剪贴板 - 代码日志

于 2021-10-26T05:50:35.147 回答
-1

复制剪贴板的代码片段:

在名为 ( 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 中的博客文章剪贴板访问

于 2015-11-05T09:19:09.213 回答
-2

你可以试试这个:

command = 'echo content |clip'
subprocess.check_call(command, shell=True)
于 2018-03-24T10:49:13.917 回答