Tkinter-based solution mentioned in Cameron Laird's answer:
import Tkinter
root = Tkinter.Tk()
print(root.selection_get(selection="CLIPBOARD"))
Replace "CLIPBOARD" with "PRIMARY" to get PRIMARY selection instead.
Also see this answer.
python-xlib solution, based on PrintSelection() and python-xlib/examples/get_selection.py
from Xlib import X, display as Xdisplay
def property2str(display, prop):
if prop.property_type == display.get_atom("STRING"):
return prop.value.decode('ISO-8859-1')
elif prop.property_type == display.get_atom("UTF8_STRING"):
return prop.value.decode('UTF-8')
else:
return "".join(str(c) for c in prop.value)
def get_selection(display, window, bufname, typename):
bufid = display.get_atom(bufname)
typeid = display.get_atom(typename)
propid = display.get_atom('XSEL_DATA')
incrid = display.get_atom('INCR')
window.change_attributes(event_mask = X.PropertyChangeMask)
window.convert_selection(bufid, typeid, propid, X.CurrentTime)
while True:
ev = display.next_event()
if ev.type == X.SelectionNotify and ev.selection == bufid:
break
if ev.property == X.NONE:
return None # request failed, e.g. owner can't convert to target format type
else:
prop = window.get_property(propid, X.AnyPropertyType, 0, 2**31-1, 1)
if prop.property_type == incrid:
result = ""
while True:
while True:
ev = display.next_event()
if ev.type == X.PropertyNotify and ev.atom == propid and ev.state == X.PropertyNewValue:
break
prop = window.get_property(propid, X.AnyPropertyType, 0, 2**31-1, 1)
if len(prop.value) == 0:
break
result += property2str(display, prop)
return result
else:
return property2str(display, prop)
display = Xdisplay.Display()
window = display.screen().root.create_window(0,0, 1,1, 0, X.CopyFromParent)
print( get_selection(display, window, "CLIPBOARD", "UTF8_STRING") or \
get_selection(display, window, "CLIPBOARD", "STRING") )
Answer from x11user on Stack Overflow
» pip install clipboard
Tkinter-based solution mentioned in Cameron Laird's answer:
import Tkinter
root = Tkinter.Tk()
print(root.selection_get(selection="CLIPBOARD"))
Replace "CLIPBOARD" with "PRIMARY" to get PRIMARY selection instead.
Also see this answer.
python-xlib solution, based on PrintSelection() and python-xlib/examples/get_selection.py
from Xlib import X, display as Xdisplay
def property2str(display, prop):
if prop.property_type == display.get_atom("STRING"):
return prop.value.decode('ISO-8859-1')
elif prop.property_type == display.get_atom("UTF8_STRING"):
return prop.value.decode('UTF-8')
else:
return "".join(str(c) for c in prop.value)
def get_selection(display, window, bufname, typename):
bufid = display.get_atom(bufname)
typeid = display.get_atom(typename)
propid = display.get_atom('XSEL_DATA')
incrid = display.get_atom('INCR')
window.change_attributes(event_mask = X.PropertyChangeMask)
window.convert_selection(bufid, typeid, propid, X.CurrentTime)
while True:
ev = display.next_event()
if ev.type == X.SelectionNotify and ev.selection == bufid:
break
if ev.property == X.NONE:
return None # request failed, e.g. owner can't convert to target format type
else:
prop = window.get_property(propid, X.AnyPropertyType, 0, 2**31-1, 1)
if prop.property_type == incrid:
result = ""
while True:
while True:
ev = display.next_event()
if ev.type == X.PropertyNotify and ev.atom == propid and ev.state == X.PropertyNewValue:
break
prop = window.get_property(propid, X.AnyPropertyType, 0, 2**31-1, 1)
if len(prop.value) == 0:
break
result += property2str(display, prop)
return result
else:
return property2str(display, prop)
display = Xdisplay.Display()
window = display.screen().root.create_window(0,0, 1,1, 0, X.CopyFromParent)
print( get_selection(display, window, "CLIPBOARD", "UTF8_STRING") or \
get_selection(display, window, "CLIPBOARD", "STRING") )
I favor a Tkinter-based solution over one which requires pygtk, simply because of the potential the latter has for installation challenges. Given this, my recommendation to Alvin Smith is to read: Cut & Paste Text Between Tkinter Widgets
You can use this code in a Tkinter event handler (from python-list via Tkinter Clipboard access):
data = event.widget.selection_get(selection="CLIPBOARD"))
Python - Getting and setting clipboard data with subprocesses - Stack Overflow
linux - Is there a way to directly send a python output to clipboard? - Stack Overflow
How to copy to the clipboard using python?
copykitten: the missing clipboard library for Python
Videos
For Linux you could use your original code using the xclip utility instead of pbpaste/pbcopy:
import subprocess
def getClipboardData():
p = subprocess.Popen(['xclip','-selection', 'clipboard', '-o'], stdout=subprocess.PIPE)
retcode = p.wait()
data = p.stdout.read()
return data
def setClipboardData(data):
p = subprocess.Popen(['xclip','-selection','clipboard'], stdin=subprocess.PIPE)
p.stdin.write(data)
p.stdin.close()
retcode = p.wait()
xclip's parameters:
-selection clipboard: operates over the clipboard selection (X Window have multiple "clipboards"-o: read from desired selection
You should notice that this solution operates over binary data. To storing a string you can use:
setClipboardData('foo'.encode())
And lastly if you are willing to use your program within a shell piping look my question about a issue.
For windows,
import win32clipboard
# set clipboard data
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText('testing 123')
win32clipboard.CloseClipboard()
# get clipboard data
win32clipboard.OpenClipboard()
data = win32clipboard.GetClipboardData()
win32clipboard.CloseClipboard()
print data
Single library across all platforms - http://coffeeghost.net/2010/10/09/pyperclip-a-cross-platform-clipboard-module-for-python/
» pip install klembord
You can use an external program, xsel:
from subprocess import Popen, PIPE
p = Popen(['xsel','-pi'], stdin=PIPE)
p.communicate(input='Hello, World')
With xsel, you can set the clipboard you want to work on.
-pworks with thePRIMARYselection. That's the middle click one.-sworks with theSECONDARYselection. I don't know if this is used anymore.-bworks with theCLIPBOARDselection. That's yourCtrl + Vone.
Read more about X's clipboards here and here.
A quick and dirty function I created to handle this:
def paste(str, p=True, c=True):
from subprocess import Popen, PIPE
if p:
p = Popen(['xsel', '-pi'], stdin=PIPE)
p.communicate(input=str)
if c:
p = Popen(['xsel', '-bi'], stdin=PIPE)
p.communicate(input=str)
paste('Hello', False) # pastes to CLIPBOARD only
paste('Hello', c=False) # pastes to PRIMARY only
paste('Hello') # pastes to both
You can also try pyGTK's clipboard :
import pygtk
pygtk.require('2.0')
import gtk
clipboard = gtk.clipboard_get()
clipboard.set_text('Hello, World')
clipboard.store()
This works with the Ctrl + V selection for me.
As it was posted in another answer, if you want to solve that within python, you can use Pyperclip which has the added benefit of being cross-platform.
>>> import pyperclip
>>> pyperclip.copy('The text to be copied to the clipboard.')
>>> pyperclip.paste()
'The text to be copied to the clipboard.'
» pip install pyperclip
I'm using centos 7, python3.5
Doing how to Automate the boring stuff.
The book uses pyperclip, I downloaded it using:
pip install pyperclip
It seems i am missing some modules: PyQt4 and gtk
pip doesn't recognize them:
pip install gtk
pip install PyQt4
Could not find a version that satisfies the requirement gtk (from versions: ) No matching distribution found for gtk
I'm guessing I'm also missing some dependencies, but pip should still recognize these packages according to this pdf on page 7
https://media.readthedocs.org/pdf/pyperclip/latest/pyperclip.pdf
any suggestions?
thanks.
EDIT: Thanks for the replies
I was finally able to download xclip from here : http://pkgs.repoforge.org/xclip/
after installation, pyperclip is working great.
What My Project Does
copykitten is a clipboard library with support for text and images and a simple API. It's built around Rust arboard library. Thanks to this, it's multiplatform and doesn't require any dependencies.
Target Audience
Developers building CLI/GUI/TUI applications. The library has beta status on PyPI, but the underlying Rust library is pretty stable, being used in commercial projects like Bitwarden and 1Password.
Comparison
There are lots of other clipboard libraries for Python: pyperclip, jaraco.clipboard, pyclip, just to name a few. However, most of them are not maintained for years and require the presence of additional libraries or tools in the operating system. copykitten doesn't suffer from these shortcomings.
A bit of history
Throughout my years with Python there were several times when I needed to use the clipboard in my applications and every time I had to fall back to some shaky methods like asking the end user to install xclip and calling subprocess.run. This never felt great.
Right now I'm making a multiplayer TUI game (maybe I’ll showcase it later too :) ), where users can copy join game codes into the clipboard to easily share it (much like Among Us). This is how I came to the idea of making such a library. I also wanted to try Rust for a long time, and so this all just clicked in my head instantly.
I had fun building it and definitely had some pain too and learned a bit of nitty-gritty details about how clipboards work in different operating systems. Now I hate Windows.
With this post I hope to gain some attention to the project so that I can receive feedback about the issues and maybe feature requests and spread the word that there's a modern, convenient alternative to the existing packages.
Feel free to try it out: https://github.com/Klavionik/copykitten