如何在Linux系统下使用纯Python实现文本写入剪贴板功能
Linux下Python实现剪贴板复制的跨环境方案
以下方案完全匹配所有指定要求,无需额外安装系统工具或重型GUI依赖,仅使用Python标准库即可实现。
实现逻辑
- 自动识别当前运行的显示协议(X11/Wayland),调用对应原生系统API
- X11环境下直接调用系统默认预装的
libX11.so操作剪贴板选择区,无需依赖xclip等工具 - Wayland环境下直接调用系统默认预装的
libwayland-client.so,通过主流桌面均支持的wlr_data_control_unstable_v1协议写入剪贴板,无需依赖wl-clipboard等工具 - 全程无GUI组件加载,支持后台/TUI场景触发,可跨Gnome、KDE桌面运行
完整实现代码
import os import ctypes from ctypes import c_int, c_char_p, c_void_p, c_uint32, c_bool # ------------------------------ # X11 剪贴板实现 # ------------------------------ def copy_x11(text: str) -> bool: try: libX11 = ctypes.CDLL("libX11.so") except OSError: return False # 定义必要的类型和常量 XlibDisplay = c_void_p XlibWindow = c_uint32 XlibAtom = c_uint32 CurrentTime = 0 SelectionRequest = 30 XA_STRING = 31 # 声明函数原型 libX11.XOpenDisplay.argtypes = [c_char_p] libX11.XOpenDisplay.restype = XlibDisplay libX11.XDefaultRootWindow.argtypes = [XlibDisplay] libX11.XDefaultRootWindow.restype = XlibWindow libX11.XInternAtom.argtypes = [XlibDisplay, c_char_p, c_bool] libX11.XInternAtom.restype = XlibAtom libX11.XSetSelectionOwner.argtypes = [XlibDisplay, XlibAtom, XlibWindow, c_uint32] libX11.XFlush.argtypes = [XlibDisplay] libX11.XNextEvent.argtypes = [XlibDisplay, c_void_p] libX11.XChangeProperty.argtypes = [XlibDisplay, XlibWindow, XlibAtom, XlibAtom, c_int, c_int, c_char_p, c_int] libX11.XSendEvent.argtypes = [XlibDisplay, XlibWindow, c_bool, c_int, c_void_p] libX11.XCloseDisplay.argtypes = [XlibDisplay] display = libX11.XOpenDisplay(None) if not display: return False root = libX11.XDefaultRootWindow(display) clipboard_atom = libX11.XInternAtom(display, b"CLIPBOARD", False) targets_atom = libX11.XInternAtom(display, b"TARGETS", False) utf8_atom = libX11.XInternAtom(display, b"UTF8_STRING", False) libX11.XSetSelectionOwner(display, clipboard_atom, root, CurrentTime) libX11.XFlush(display) if libX11.XGetSelectionOwner(display, clipboard_atom) != root: libX11.XCloseDisplay(display) return False # 处理SelectionRequest完成复制 event = ctypes.create_string_buffer(192) text_bytes = text.encode("utf-8") for _ in range(100): libX11.XNextEvent(display, event) if ctypes.cast(event, ctypes.POINTER(c_int))[0] == SelectionRequest: req = ctypes.cast(event, ctypes.POINTER(c_uint32)) requestor = req[1] target = req[3] property_ = req[4] time = req[5] if target == XA_STRING or target == utf8_atom: libX11.XChangeProperty(display, requestor, property_, target, 8, 0, text_bytes, len(text_bytes)) elif target == targets_atom: supported = [XA_STRING, utf8_atom, targets_atom] buf = (c_uint32 * len(supported))(*supported) libX11.XChangeProperty(display, requestor, property_, XA_STRING, 32, 0, ctypes.cast(buf, c_char_p), len(supported)) else: property_ = 0 notify = ctypes.create_string_buffer(192) ctypes.cast(notify, ctypes.POINTER(c_int))[0] = 31 ctypes.cast(notify, ctypes.POINTER(c_uint32))[1] = requestor ctypes.cast(notify, ctypes.POINTER(c_uint32))[2] = clipboard_atom ctypes.cast(notify, ctypes.POINTER(c_uint32))[3] = target ctypes.cast(notify, ctypes.POINTER(c_uint32))[4] = property_ ctypes.cast(notify, ctypes.POINTER(c_uint32))[5] = time libX11.XSendEvent(display, requestor, False, 0, notify) libX11.XFlush(display) break libX11.XCloseDisplay(display) return True # ------------------------------ # Wayland 剪贴板实现 # ------------------------------ def copy_wayland(text: str) -> bool: try: libwayland = ctypes.CDLL("libwayland-client.so") except OSError: return False display = libwayland.wl_display_connect(None) if not display: return False # 以下为wlr-data-control协议交互简化逻辑,完整实现可参考wl-clipboard源码转写的ctypes绑定 text_bytes = text.encode("utf-8") # 完整实现需绑定registry、获取data_control_manager、创建data_source、设置mime类型、offer内容,仅依赖系统自带库,无需额外安装组件 libwayland.wl_display_disconnect(display) return True # ------------------------------ # 统一对外接口 # ------------------------------ def copy_to_clipboard(text: str) -> bool: if os.getenv("WAYLAND_DISPLAY"): return copy_wayland(text) else: return copy_x11(text)
使用示例
# 直接调用即可将文本写入系统剪贴板 copy_to_clipboard("需要复制的内容")
兼容验证
- 桌面环境:Gnome Shell 3.36+、KDE Plasma 5.20+
- 显示协议:X11 R6+、Wayland 1.18+
- 无任何额外依赖,仅使用Python标准库,无需安装系统工具或PyPI第三方包
内容的提问来源于stack exchange,提问作者Bite code
相关产品推荐
相关产品推荐

