[Python] send text to the Mac clipboard

Posted in :

滿有趣的,居然有套件:
https://pypi.python.org/pypi/clipboard/

pip install clipboard

A cross platform clipboard operation library of Python. Works for Windows, Mac and Linux.

Well, as I was trying to implement this, I realize that everything is included in pyperclip already: https://pypi.python.org/pypi/pyperclip/

But anyway, clipboard is a better name. You are free to choose:-) I might add more features to it.

Usage:

import clipboard
clipboard.copy("abc")  # now the clipboard content will be string "abc"
text = clipboard.paste()  # text will have the content of clipboard

上面套件,會有 ascii 和 utf-8 轉碼問題,要解決應該很快,但作者似乎已經有 3年多沒維護了。


解法2號:

A simple way:

cmd = 'echo %s | tr -d "\n" | pbcopy' % str
os.system(cmd)

解法3號:

A cross-platform way:
http://stackoverflow.com/a/4203897/805627

from Tkinter import Tk
r = Tk()
r.withdraw()
r.clipboard_clear()
r.clipboard_append('i can has clipboardz?')
r.destroy()

解法 4號:

https://github.com/asweigart/pyperclip

Usage

>>> import pyperclip
>>> pyperclip.copy('The text to be copied to the clipboard.')
>>> pyperclip.paste()
'The text to be copied to the clipboard.'

解法 5號,我是用這一組:

"""
Pyperclip

A cross-platform clipboard module for Python. (only handles plain text for now)
By Al Sweigart [email protected]
BSD License

Usage:
 import pyperclip
 pyperclip.copy('The text to be copied to the clipboard.')
 spam = pyperclip.paste()

On Windows, no additional modules are needed.
On Mac, this module makes use of the pbcopy and pbpaste commands, which should come with the os.
On Linux, this module makes use of the xclip or xsel commands, which should come with the os. Otherwise run "sudo apt-get install xclip" or "sudo apt-get install xsel"
 Otherwise on Linux, you will need the gtk or PyQt4 modules installed.

The gtk module is not available for Python 3, and this module does not work with PyGObject yet.
"""

__version__ = '1.5.6'

import platform, os
from subprocess import call, Popen, PIPE


def _pasteWindows():
 CF_UNICODETEXT = 13
 d = ctypes.windll
 d.user32.OpenClipboard(None)
 handle = d.user32.GetClipboardData(CF_UNICODETEXT)
 data = ctypes.c_wchar_p(handle).value
 d.user32.CloseClipboard()
 return data


def _copyWindows(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(None)
 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 _pasteCygwin():
 CF_UNICODETEXT = 13
 d = ctypes.cdll
 d.user32.OpenClipboard(None)
 handle = d.user32.GetClipboardData(CF_UNICODETEXT)
 data = ctypes.c_wchar_p(handle).value
 d.user32.CloseClipboard()
 return data


def _copyCygwin(text):
 GMEM_DDESHARE = 0x2000
 CF_UNICODETEXT = 13
 d = ctypes.cdll
 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(None)
 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 _copyOSX(text):
 text = str(text)
 p = Popen(['pbcopy', 'w'], stdin=PIPE)
 try:
 # works on Python 3 (bytes() requires an encoding)
 p.communicate(input=bytes(text, 'utf-8'))
 except TypeError:
 # works on Python 2 (bytes() only takes one argument)
 p.communicate(input=bytes(text))


def _pasteOSX():
 p = Popen(['pbpaste', 'r'], stdout=PIPE)
 stdout, stderr = p.communicate()
 return bytes.decode(stdout)


def _pasteGtk():
 return gtk.Clipboard().wait_for_text()


def _copyGtk(text):
 global cb
 text = str(text)
 cb = gtk.Clipboard()
 cb.set_text(text)
 cb.store()


def _pasteQt():
 return str(cb.text())


def _copyQt(text):
 text = str(text)
 cb.setText(text)


def _copyXclip(text):
 p = Popen(['xclip', '-selection', 'c'], stdin=PIPE)
 try:
 # works on Python 3 (bytes() requires an encoding)
 p.communicate(input=bytes(text, 'utf-8'))
 except TypeError:
 # works on Python 2 (bytes() only takes one argument)
 p.communicate(input=bytes(text))


def _pasteXclip():
 p = Popen(['xclip', '-selection', 'c', '-o'], stdout=PIPE)
 stdout, stderr = p.communicate()
 return bytes.decode(stdout)


def _copyXsel(text):
 p = Popen(['xsel', '-i'], stdin=PIPE)
 try:
 # works on Python 3 (bytes() requires an encoding)
 p.communicate(input=bytes(text, 'utf-8'))
 except TypeError:
 # works on Python 2 (bytes() only takes one argument)
 p.communicate(input=bytes(text))


def _pasteXsel():
 p = Popen(['xsel', '-o'], stdout=PIPE)
 stdout, stderr = p.communicate()
 return bytes.decode(stdout)



# Determine the OS/platform and set the copy() and paste() functions accordingly.
if 'cygwin' in platform.system().lower():
 _functions = 'Cygwin' # for debugging
 import ctypes
 paste = _pasteCygwin
 copy = _copyCygwin
elif os.name == 'nt' or platform.system() == 'Windows':
 _functions = 'Windows' # for debugging
 import ctypes
 paste = _pasteWindows
 copy = _copyWindows
elif os.name == 'mac' or platform.system() == 'Darwin':
 _functions = 'OS X pbcopy/pbpaste' # for debugging
 paste = _pasteOSX
 copy = _copyOSX
elif os.name == 'posix' or platform.system() == 'Linux':
 # Determine which command/module is installed, if any.
 xclipExists = call(['which', 'xclip'],
 stdout=PIPE, stderr=PIPE) == 0

 xselExists = call(['which', 'xsel'],
 stdout=PIPE, stderr=PIPE) == 0

 gtkInstalled = False
 try:
 # Check it gtk is installed.
 import gtk
 gtkInstalled = True
 except ImportError:
 pass

 if not gtkInstalled:
 # Check if PyQt4 is installed.
 PyQt4Installed = False
 try:
 import PyQt4.QtCore
 import PyQt4.QtGui
 PyQt4Installed = True
 except ImportError:
 pass

 # Set one of the copy & paste functions.
 if xclipExists:
 _functions = 'xclip command' # for debugging
 paste = _pasteXclip
 copy = _copyXclip
 elif gtkInstalled:
 _functions = 'gtk module' # for debugging
 paste = _pasteGtk
 copy = _copyGtk
 elif PyQt4Installed:
 _functions = 'PyQt4 module' # for debugging
 app = PyQt4.QtGui.QApplication([])
 cb = PyQt4.QtGui.QApplication.clipboard()
 paste = _pasteQt
 copy = _copyQt
 elif xselExists:
 # TODO: xsel doesn't seem to work on Raspberry Pi (my test Linux environment). Putting this as the last method tried.
 _functions = 'xsel command' # for debugging
 paste = _pasteXsel
 copy = _copyXsel
 else:
 raise Exception('Pyperclip requires the xclip or xsel application, or the gtk or PyQt4 module.')
else:
 raise RuntimeError('pyperclip does not support your system.')

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *