【问题标题】:How can Python access the X11 clipboard?Python如何访问X11剪贴板?
【发布时间】:2010-10-10 21:21:36
【问题描述】:

我希望我的 Python 脚本能够通过 x11 向剪贴板复制和粘贴(这样它就可以在 Linux 上运行)。谁能指出我可以查看的具体资源,或者我必须掌握的概念?

这可能与http://python-xlib.sourceforge.net 的 Python X 库有关吗?

【问题讨论】:

  • 请注意,使用xlib 或以下答案中的其他解决方案只会复制/粘贴文本;而现在大多数应用程序也复制/粘贴图像或其他格式:对于这些,您可能需要 gtkqt 库。此外,在大多数应用程序中,X11 剪贴板是使用鼠标中键粘贴的,但不是使用 ctrl-v 粘贴的。

标签: python copy clipboard x11 paste


【解决方案1】:

基于Tkinter的解决方案Cameron Laird's answer中提到:

import Tkinter
root = Tkinter.Tk()
print(root.selection_get(selection="CLIPBOARD"))

将“CLIPBOARD”替换为“PRIMARY”以获得PRIMARY 选择。

另见this answer

python-xlib 解决方案,基于PrintSelection()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") )

【讨论】:

    【解决方案2】:

    我更喜欢基于 Tkinter 的解决方案,而不是需要 pygtk 的解决方案,仅仅是因为后者可能会面临安装挑战。鉴于此,我对 Alvin Smith 的建议是:Cut & Paste Text Between Tkinter Widgets

    您可以在 Tkinter 事件处理程序中使用此代码(来自python-list 通过Tkinter Clipboard access):

    data =  event.widget.selection_get(selection="CLIPBOARD"))
    

    【讨论】:

    • 第一个链接坏了。
    【解决方案3】:

    You can do this with pygtk。一个干净的解决方案,但根据您的应用程序可能有点矫枉过正。

    另一种获取google-hits 的方法是对xsel 进行系统调用。

    【讨论】:

    • 第一个链接坏了
    【解决方案4】:

    你可能会发现这个帖子很有用:How does X11 clipboard handle multiple data formats?

    【讨论】:

      【解决方案5】:

      使用clipboard 模块

      首先,使用pip3 安装clipboard 模块:

      $ sudo pip3 install clipboard
      

      使用这个跨平台模块(Linux、Mac、Windows)非常简单:

      import clipboard
      clipboard.copy('text')   # Copy to the clipboard.
      text = clipboard.paste()   # Copy from the clipboard.
      

      【讨论】:

      • 但这不允许您使用PRIMARY 选择,是吗?
      • 根据clipboard的作者,这可能是一个更好的选择:https://github.com/asweigart/pyperclip
      猜你喜欢
      • 2010-11-22
      • 1970-01-01
      • 2011-02-20
      • 2010-11-09
      • 1970-01-01
      • 2016-01-02
      • 2021-11-18
      • 2013-07-05
      相关资源
      最近更新 更多