How do I copy a string to the clipboard?

Viewed 211980

I'm trying to make a basic Windows application that builds a string out of user input and then adds it to the clipboard. How do I copy a string to the clipboard using Python?

27 Answers

Here's the most easy and reliable way I found if you're okay depending on Pandas. However I don't think this is officially part of the Pandas API so it may break with future updates. It works as of 0.25.3

from pandas.io import clipboard
clipboard.copy("test")

Looks like you need to add win32clipboard to your site-packages. It's part of the pywin32 package

Use pyperclip module

Install using pip pip install pyperclip.

Copy text "Hello World!" to clip board

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

You can use Ctrl+V anywhere to paste this somewhere.

Paste the copied text using python

pyperclip.paste() # This returns the copied text of type <class 'str'>

Not all of the answers worked for my various python configurations so this solution only uses the subprocess module. However, copy_keyword has to be pbcopy for Mac or clip for Windows:

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

Here's some more extensive code that automatically checks what the current operating system is:

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)

In addition to Mark Ransom's answer using ctypes: This does not work for (all?) x64 systems since the handles seem to be truncated to int-size. Explicitly defining args and return values helps to overcomes this problem.

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

Use python's clipboard library!

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

Clipboard contains 'abc' now. Happy pasting!

also you can use > clipboard

import clipboard

def copy(txt):
    clipboard.copy(txt)
    
copy("your txt")

If (and only if) the application already uses Qt, you can use this (with the advantage of no additional third party dependency)

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)

This requires a Qt application object to be already constructed, so it should not be used unless the application already uses Qt.

Besides, as usual, in X systems (and maybe other systems too), the content only persist until the application exists unless you use something like parcellite or xclipboard.

Documentation:

See also: python - PyQT - copy file to clipboard - Stack Overflow

The snippet I share here take advantage of the ability to format text files: what if you want to copy a complex output to the clipboard ? (Say a numpy array in column or a list of something)

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

works only for windows, can be adapted for linux or mac I guess. Maybe a bit complicated...

example:

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

Ctrl+V in any text editor :

ET
phone
home

You can use winclip32 module! install:

pip install winclip32

to copy:

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

to get:

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

for more informations: https://pypi.org/project/winclip32/

On Windows, you can use this. No external dependencies neither have to open sub-process:

import win32clipboard


def to_clipboard(txt):

    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardText(txt)
    win32clipboard.CloseClipboard()

Solution with stdlib, without security issues

The following solution works in Linux without any additional library and without the risk of executing unwanted code in your shell.

import subprocess

def to_clipboard(text: str) -> None:
    sp = subprocess.Popen(["xclip"], stdin=subprocess.PIPE, 
                                      stdout=subprocess.PIPE)
    sp.communicate(text.encode("utf8"))

Note that there multiple clipboard in Linux, the you use with the Middle Mouse (Primary) and yet another that you use pressing STRG+C,STRG+V.

You can define which clipboard is used by adding a selection parameter i.e. ["xclip", "-selection", "clipboard"]. See the man xclip for details.

If you using Windows, just replace xclip with clip.

This solution works without Tkinter, which not available some Python installations (i.e. the custom build I am currently using).

Related