How do I copy a string to the clipboard?
Asked Answered
D

31

284

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?

Dinner answered 23/2, 2009 at 22:38 Comment(4)
Related to this question.Barnes
jaraco.clipboard does it (too): clipboard.copy(variable)Arroba
Also see my answer to a related question about copying to the clipboard using Tkinter without showing a window. It includes a Python function that replaces/returns clipboard text using Tkinter.Margarite
For rich text, windows - Accessing alternate clipboard formats from python - Stack Overflow has some pointers.Unsuspecting
T
378

Actually, pywin32 and ctypes seem to be an overkill for this simple task. tkinter is a cross-platform GUI framework, which ships with Python by default and has clipboard accessing methods along with other cool stuff.

If all you need is to put some text to system clipboard, this will do it:

from tkinter import Tk # in Python 2, use "Tkinter" instead 
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()

And that's all, no need to mess around with platform-specific third-party libraries.

If you are using Python 2, replace tkinter with Tkinter.

Tadeo answered 17/11, 2010 at 11:31 Comment(22)
Get contents of clipboard: result = r.selection_get(selection = "CLIPBOARD")Hilariahilario
@SurDin Tkinter was renamed tkinter in python 3, so it depends on what version you're using.Expend
Cool solution, but I'm having some trouble with Unicode strings, know of any workarounds (like, convert unicode chars to an ascii equivalent)?Watkin
@kapace: related bug in Python. It is fixed now.Inaptitude
all my apps get unresponsive after pasting the contents of the clipboard with this function, strangely, getting the result works fine.Santo
@BartlomiejLewandowski as far as I can tell tkinter wont release the clipboard while you are looping anything in python.Creosol
It works if I don't call r.destroy(). Once I call that, the clipboard becomes empty and pressing Ctrl-V may cause the target app to freeze. (OS: Windows 7 x64)Hama
Whe used in a command line program, this will automatically make the target app freeze (Windows 7) untill I call r.update() or the whole script is over.Cradling
Get contents of clipboard: r.clipboard_get()Cistaceous
After the program ends, this keeps the clipboard on my Windows 7 but not on Windows 8.1, unless calling win32clipboard.GetClipboardData(win32clipboard.CF_TEXT).Nevels
If you use this in a console script this might lead to an error, that the .destroy() function will not work ("can't invoke "event" command: application has been destroyed while executing [...]"). To prevent this, call r.update() before r.destroy.Duna
This doesn't work at all for me using Python 2.7.2 in IDLE. the r.clipboard_get() posted by @Cistaceous prints it out to the IDLE Python shell but it isn't available in other applications (tried posting into notepad etc.)Zsa
To me this doesn't work for python 3.4, but it works for python 2.7 (yes, with tkinter instead of Tkinter)Noetic
This works on Linux / python 2.7.6 in an interactive console, but not from a script!? I tried a few tests, impossible to understand why...Entourage
is it possible to send back the data as CF_HTML using Tkinter?Arroba
In Spyder, this only works in the Python console but not in the i-Python console.Katusha
This seems to blow it up if it's appending mac address in plain text.Rutan
ctypes (a minimalist wrapper around the low-level Win32 API) is overkill, so people should use TK? This answer is very, very confused...Sepia
This seems to be slower than pywin32Georganngeorge
This is a good example for a very old outdated answer clinging on top, while you have to scroll down, looking at the “answered” dates to find the currently best way to do it.Risser
The pyperclip module below worked for me. The above script rendered apps unresponsive.Sumba
Nope. This one either hams any app that so much as accesses the clipboard or doesn't work at all. Keep awaySundaysundberg
K
105

I didn't have a solution, just a workaround.

Windows Vista onwards has an inbuilt command called clip that takes the output of a command from command line and puts it into the clipboard. For example, ipconfig | clip.

So I made a function with the os module which takes a string and adds it to the clipboard using the inbuilt Windows solution.

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.

As previously noted in the comments however, one downside to this approach is that the echo command automatically adds a newline to the end of your text. To avoid this you can use a modified version of the command:

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

If you are using Windows XP it will work just following the steps in Copy and paste from Windows XP Pro's command prompt straight to the Clipboard.

Kobold answered 23/2, 2012 at 9:6 Comment(11)
is there any limitations on the length of the text?Rohn
what happens if text contains | calc.exe ?Serene
@WilliBallenthin then you need to wrap it in double quotes. But what if it CONTAINS double quotes? Then you need to double the double quotes. text with " quotes and | pipe becomes "text with "" quotes and | pipe" Although this may have problems on systems with windows older than 95.Conch
Your solution seem sperfect! Now I just need to find a way to pass tabs "\t"... All other solution using a GUI library will freeze untill a GUI event happens.Cradling
Extremely insecure function... Content sent to your clipboard is now an entry vector and thus increases your attack surface.Scandalmonger
I also need support for newlines, so I modified this to use type. I write my text to file, and use the command type myfile.txt | clip.Wringer
Although this is the best answer to me, it has an issue (Python 3.5, Windows 10); an unwanted newline is always added at the end of the string. How to avoid it?Solace
This is extremely weak to injection. Please never use this if the user has any input in what's to be copied that allows for actual text to be entered.Dishpan
How can you empty the clipboard? If you run it twice, the new text is copied after the one that was already copied.Blindfish
Building on @Wringer "write to file" solution, you could also use this variation clip < myfile.txt.Greige
Instead of using os.system, use subprocess.run, which gives you more control over stdin. For example subprocess.run(['clip'], stdin=open(somefile,'rb'))Anticlimax
S
66

The simplest way is with pyperclip. Works in python 2 and 3.

To install this library, use:

pip install pyperclip

Example usage:

import pyperclip

pyperclip.copy("your string")

If you want to get the contents of the clipboard:

clipboard_content = pyperclip.paste()
Sharpen answered 8/3, 2017 at 12:21 Comment(2)
pyperclip.paste() does not work with images just returns NoneType error. but works with right click and copy then using python to paste the copied results.Hort
@Hort the question doesn't ask about copying an image to the clipboard. However, you could use the ImageGrab.grabclipboard() module of the Pillow library (pip install Pillow).Sharpen
S
65

You can use pyperclip - cross-platform clipboard module. Or Xerox - similar module, except requires the win32 Python module to work on Windows.

Swung answered 2/7, 2014 at 5:43 Comment(4)
pyperclip doesn't do Unicode on Windows. win32clipboard does.Nevels
My pyperclip patch was accepted; c:\python34\Scripts\pip install --upgrade pyperclip to handle Unicode text.Nevels
It took me a while to find out that this is pyperclip, not paperclip. Also, as on 2016, pyperclip works with Unicode characters too. I have tested characters ±°©©αβγθΔΨΦåäö to work on Win10 64-bit, with Python 3.5 and pyperclip 1.5.27.Spinnaker
pyperclip also works on Mac and Linux too (not just Windows), which is nice.Infantile
Q
52

You can use the excellent pandas, which has a built in clipboard support, but you need to pass through a DataFrame.

import pandas as pd
df=pd.DataFrame(['Text to copy'])
df.to_clipboard(index=False,header=False)
Quintonquintuple answered 23/3, 2016 at 12:36 Comment(8)
+1. I like this solution. It's even simpler than the accepted Tkinter solution. If you imported pandas anyways, there is no additional overhead. It also works across all platforms. It does not even (in most cases) require installing a new package.Jhvh
this uses pyperclip anyway, so better use pyperpclipBearden
For most people (i.e. me), pandas is readily available but import pyperclip doesn't work. So I don't agree with "better use pyperclip".Etherege
If you're restricted to using just pandas, you could use pyperclip directly through import pandas.io.clipboard as pyperclip or name it whatever you want. That's where it sits within pandas, at leastBlowtube
This seems to add a newline character to the string you copyCalculable
This is by far the simplest and most elegant solution for this problem. Thank you very much for sharing this.Sheeb
pandas is soooo gooooodGrados
If you already have pandas loaded and you don't want to keep the dataframe, this can be reduced to a single line: pd.DataFrame(['Text to copy']).to_clipboard(excel=False,index=False,header=False) The excel=False parameter removes the newline mentioned in the comment from @GijsvanOortTeplitz
W
44

You can also use ctypes to tap into the Windows API and avoid the massive pywin32 package. This is what I use (excuse the poor style, but the idea is there):

import ctypes

# Get required functions, strcpy..
strcpy = ctypes.cdll.msvcrt.strcpy
OpenClipboard = ctypes.windll.user32.OpenClipboard    # Basic clipboard functions
EmptyClipboard = ctypes.windll.user32.EmptyClipboard
GetClipboardData = ctypes.windll.user32.GetClipboardData
SetClipboardData = ctypes.windll.user32.SetClipboardData
CloseClipboard = ctypes.windll.user32.CloseClipboard
GlobalAlloc = ctypes.windll.kernel32.GlobalAlloc    # Global memory allocation
GlobalLock = ctypes.windll.kernel32.GlobalLock     # Global memory Locking
GlobalUnlock = ctypes.windll.kernel32.GlobalUnlock
GMEM_DDESHARE = 0x2000

def Get():
  OpenClipboard(None) # Open Clip, Default task

  pcontents = GetClipboardData(1) # 1 means CF_TEXT.. too lazy to get the token thingy...

  data = ctypes.c_char_p(pcontents).value

  #GlobalUnlock(pcontents) ?
  CloseClipboard()

  return data

def Paste(data):
  OpenClipboard(None) # Open Clip, Default task

  EmptyClipboard()

  hCd = GlobalAlloc(GMEM_DDESHARE, len(bytes(data,"ascii")) + 1)

  pchData = GlobalLock(hCd)

  strcpy(ctypes.c_char_p(pchData), bytes(data, "ascii"))

  GlobalUnlock(hCd)

  SetClipboardData(1, hCd)

  CloseClipboard()
Watkin answered 7/8, 2010 at 3:33 Comment(5)
At least in python 2.6 x64, I had to change bytes(data,"ascii") to bytes(data). Thanks for answering the question, I can't use pywin32 or tk or a number of other things and this works.Rightness
No worries, but note that the data returned from the clipboard is actually in another encoding, I believe it is Windows CP-1252. This was somewhat hacked together, but if you don't use the correct encoding then non-ascii characters will raise an error or decode incorrectly.Watkin
Variable names should not need comments, and everything should support Unicode.Nevels
bytes(data, "mbcs") will work with windows default encoding. Allowed me to load this to the clipboard "másreas ç saod é í ó u* ü ö ï/" and read it back correctly.Greatuncle
using mbcs gives me this: OSError: exception: access violation writing 0x0000000000000000Georganngeorge
J
43

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")
Jowl answered 23/11, 2019 at 20:45 Comment(3)
Works for me, except I might use from pandas.io import clipboard then clipboard.copy(...) to avoid confusion with other copy methods.Debar
that is just a wrapper around pyperclip! (or to be more precise... pandas simply puts a copy of some pyperclip version into their src )Trilly
This is how it's done with more recent versions of pandas (tested with 1.4.1 and 2.1.1): pandas.io.clipboards.to_clipboard(obj, excel=False)Backbreaker
S
13

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'>
Soucy answered 23/3, 2021 at 10:57 Comment(0)
U
12

For some reason I've never been able to get the Tk solution to work for me. kapace's solution is much more workable, but the formatting is contrary to my style and it doesn't work with Unicode. Here's a modified version.

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

The above has changed since this answer was first created, to better cope with extended Unicode characters and Python 3. It has been tested in both Python 2.7 and 3.5, and works even with emoji such as \U0001f601 (😁).

Update 2021-10-26: This was working great for me in Windows 7 and Python 3.8. Then I got a new computer with Windows 10 and Python 3.10, and it failed for me the same way as indicated in the comments. This post gave me the answer. The functions from ctypes don't have argument and return types properly specified, and the defaults don't work consistently with 64-bit values. I've modified the above code to include that missing information.

Unprepared answered 5/9, 2014 at 3:11 Comment(16)
@CeesTimmerman I'd love to have a Windows 8.1 system to test why. I might have a chance to investigate later today. Are you sure you had text in the clipboard?Unprepared
Yes. I've extensively tested clipboard code in Python over the past three days.Nevels
The put() function also needs work; emoji "📋" (\U0001f400) is copied as "🐀" (\U0001f4cb), or "📋." turns to "📋".Nevels
@CeesTimmerman that explains it. The internal Unicode representation changed, I can't remember if it was 3.3 or 3.4. To fix it will require an explicit encoding to UTF-16. It's not a bug.Unprepared
3.3, and len(data.encode('utf-16-le')) + 2 fixed it.Nevels
I get "NameError: name 'unicode' is not defined. Either I'm overlooking something basic, or this script is missing this variable.Jointer
@YngvarKristiansen it's a Python 2 vs. Python 3 thing. This script needs some work for Python 3, I'll try to fix it later.Unprepared
@YngvarKristiansen I finally got around to making those changes. I'm confident now that this code works for most modern versions of Python and every possible Unicode character.Unprepared
@CeesTimmerman I made this clipboard code a lot more robust this summer, not sure if you had a chance to see those changes.Unprepared
ctypes.memmove(pcontents, data, len(data)) gives an error: OSError: exception: access violation writing 0x0000000000000000Georganngeorge
@SeakyLone that probably means there was no text on the clipboard.Unprepared
@MarkRansom Thanks for replying. I just copied some text and called your function again. The text was removed from the clipboard. I commented out the EmptyClipboard(). The text stays but still the same error. Any idea how to fix it?Georganngeorge
@SeakyLone my bad, I thought you were trying to read from the clipboard not write to it. Your error indicates that either GlobalAlloc or GlobalLock failed, you'd need to print out handle to know which one. It's hard to see how either could fail, they're very basic Windows functions.Unprepared
@MarkRansom The handle/GlobalAlloc varies and is a very large negative number. And the pcontentsGlobalLock is always 0. FYI, I am using Windows 10 + Python 3.7.Georganngeorge
@SeakyLone then apparently it's GlobalLock that's failing. I can't tell you why that would be.Unprepared
@SeakyLone I just updated the code with a fix. It may be incomplete though, it just occurred to me that memmove would require a similar fix.Unprepared
N
12

I've tried various solutions, but this is the simplest one that passes my test:

#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'))

Tested OK in Python 3.4 on Windows 8.1 and Python 2.7 on Windows 7. Also when reading Unicode data with Unix linefeeds copied from Windows. Copied data stays on the clipboard after Python exits: "Testing the “clip—board”: 📋"

If you want no external dependencies, use this code (now part of cross-platform 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
Nevels answered 4/12, 2014 at 10:20 Comment(2)
Where do you get win32clipboard? It's not part of my Python 2.7. And why does paste use CF_TEXT instead of CF_UNICODETEXT?Unprepared
@MarkRansom pywin32, and because my test worked fine until i made it harder using 📋. I've updated the code.Nevels
L
10

If you don't like the name you can use the derivative module clipboard.

Note: It's just a selective wrapper of pyperclip

After installing, import it:

import clipboard

Then you can copy like this:

clipboard.copy("This is copied")

You can also paste the copied text:

clipboard.paste()
Load answered 25/8, 2019 at 10:35 Comment(3)
This seems like the best solution. clipboard can be installed with pip install clipboard.Honolulu
The clipboard package is just a shameless copy of the pyperclip package. As indicated by its code here.Chivalrous
its a good solution for string. What about bytes ? any solution like this to copy bytes to clipboard in single line of pythonNearly
B
10

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)
Breadth answered 17/2, 2020 at 20:53 Comment(3)
IDLE crashes when you try to paste that string.Cupriferous
@MaxDoesStuff Try it without the emoji. I don't know why that doesn't work in the default IDLE, but it works in other IDLEs.Breadth
Python 3.11 subprocess.run() docs: "The universal_newlines argument is equivalent to text and is provided for backwards compatibility." Therefore it's simpler to replace universal_newlines=True with just text=True.Riles
T
9

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

Turnaround answered 23/2, 2009 at 22:43 Comment(1)
would be a much better answer with some example code.Bushman
G
5

I think there is a much simpler solution to this.

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

Then run your program in the command line

python greeter.py | clip

This will pipe the output of your file to the clipboard

Gare answered 23/1, 2017 at 20:42 Comment(2)
It's a good solution but I imagine a lot of the python is developed and run in an IDEZestful
Or | pbcopy on macOSNortherly
B
4

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

Brock answered 21/9, 2022 at 11:39 Comment(3)
The sp.communicate call does not return, a possible solution is to add a timeout=t_in_seconds optional argument, and catch the ensuing subprocess.TimeoutExpired exception.Childish
I think thet better and simpler is subprocess.run(["xclip"], input=text.encode("utf8"))Onetime
In my test env using input didn't work.Brock
L
3

Widgets also have method named .clipboard_get() that returns the contents of the clipboard (unless some kind of error happens based on the type of data in the clipboard).

The clipboard_get() method is mentioned in this bug report:
http://bugs.python.org/issue14777

Strangely, this method was not mentioned in the common (but unofficial) online TkInter documentation sources that I usually refer to.

Limelight answered 26/10, 2013 at 4:0 Comment(0)
B
2

This is an improved answer of atomizer. Note that

  • there are 2 calls of update() and
  • inserted 200 ms delay between them.

They protect freezing applications due to an unstable state of the clipboard:

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()
Bicarb answered 18/2, 2017 at 23:13 Comment(2)
time.sleep doesnt work with tkinter. r.after is reccomendedXanthippe
In this context, the time.sleep() works perfectly.Bicarb
A
2

On Windows, you can use: pywin32.

Install it with: pip install pywin32.

Use it like this.

import win32clipboard


def to_clipboard(txt):

    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardText(txt)
    win32clipboard.CloseClipboard()
Athletic answered 28/7, 2021 at 15:29 Comment(0)
H
2

This works like a charm. It's cross platform with no dependencies. Tested on Linux and Windows.

import PySimpleGUI as sg

text = 'My text to clipboard'

# Set clipboard
sg.clipboard_set(text)

# Paste clipboard
new_text = sg.clipboard_get()
print(new_text)
Heda answered 15/8, 2023 at 5:13 Comment(2)
Thank you for the PySimpleGUI mention! It's great to see people have found the clipboard APIs and are using them.Sindee
PySimpleGUI is a dependencySepulveda
T
1
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)
Touchwood answered 14/4, 2015 at 16:41 Comment(3)
An explanation of the problem and solution would be helpful.Rebecarebecca
a function to copy text to a clipboard. using the wx python library (I never learnt TK) another solution to the question asked here.Touchwood
Feel free to edit the answer to include your explanation of problem/solution @Touchwood -- doing this generally makes answers more useful. Also, thanks for trying, but I suppose the original poster had some reason to ask for Tk specifically.Rankin
B
1

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
Bismuthous answered 10/4, 2019 at 11:23 Comment(0)
E
1

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())
Example answered 24/9, 2019 at 10:34 Comment(0)
I
1

also you can use > clipboard

import clipboard

def copy(txt):
    clipboard.copy(txt)
    
copy("your txt")
Ithaca answered 16/8, 2021 at 7:41 Comment(1)
Or just: copy = clipboard.copy, or even better from clipboard import copy.Infighting
U
1

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

Unsuspecting answered 26/10, 2021 at 5:50 Comment(0)
M
1

Pretty much, the best choice is tkinter.

It comes by default in python, and requires no requirements.

You can copy any text with it too!

Just try this:

import tkinter as _tk
def copy(text):
    root = _tk.Tk()
    root.withdraw()
    root.clipboard_clear()
    root.clipboard_append(text)
    root.destroy()
    del root

And you can now use copy() function to copy any text you want! (if its a string)

But, if you want to get text from clipboard, you can use this.

import tkinter as _tk
def paste():
    root = _tk.Tk()
    root.withdraw()
    text = root.clipboard_get()
    root.destroy()
    del root
    return text
Memling answered 1/2 at 13:20 Comment(0)
M
0

Use python's clipboard library!

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

Clipboard contains 'abc' now. Happy pasting!

Mcspadden answered 16/12, 2019 at 12:20 Comment(2)
Where do you get clipboard from? It isn't in the standard library for Anaconda Python 3.7, at least.Debar
clipboard simply imports pyperclip. Really. Nothing more.Risser
P
0

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/

Pipeline answered 9/3, 2020 at 20:0 Comment(0)
F
0

My multiplatform solution base on this question:

import subprocess
import distutils.spawn

def clipit(text):
    if distutils.spawn.find_executable("xclip"):
        # for Linux
        subprocess.run(["xclip", "-i"], input=text.encode("utf8"))
    elif distutils.spawn.find_executable("xsel"):
        # for Linux
        subprocess.run(["xsel", "--input"], input=text.encode("utf8"))
    elif distutils.spawn.find_executable("clip"):
        # for Windows
        subprocess.run(["clip"], input=text.encode("utf8"))
    else:
        import pyperclip

        print("I use module pyperclip.")
        pyperclip.copy(text)

Fructify answered 29/12, 2022 at 12:52 Comment(0)
A
0

For Windows without requiring pyperclip, also supports multiple lines.

import tempfile
import subprocess

with tempfile.NamedTemporaryFile(delete=False) as tmp:
    tmp.write(string.encode())
    tmp.close()
    cmd = 'type ' + tmp.name + '|clip'
    subprocess.check_call(cmd, shell=True)
Arly answered 10/4 at 10:23 Comment(1)
Thank you for your interest in contributing to the Stack Overflow community. This question already has quite a few answers—including one that has been extensively validated by the community. Are you certain your approach hasn’t been given previously? If so, it would be useful to explain how your approach is different, under what circumstances your approach might be preferred, and/or why you think the previous answers aren’t sufficient. Can you kindly edit your answer to offer an explanation?Phototonus
E
-1

Code snippet to copy the clipboard:

Create a wrapper Python code in a module named (clipboard.py):

import clr
clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import Clipboard
def setText(text):
    Clipboard.SetText(text)

def getText():
    return Clipboard.GetText()

Then import the above module into your code.

import io
import clipboard
code = clipboard.getText()
print code
code = "abcd"
clipboard.setText(code)

I must give credit to the blog post Clipboard Access in IronPython.

Estate answered 5/11, 2015 at 9:19 Comment(0)
B
-2

you can try this:

command = 'echo content |clip'
subprocess.check_call(command, shell=True)
Behaviorism answered 24/3, 2018 at 10:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.