[Python] Setting a persistant clipboard with multiple targets on X11

Discussão em 'Python' iniciado por Stack, Maio 20, 2025.

  1. Stack

    Stack Membro Participativo

    General overview


    I am trying to set an image in clipboard into different linux’s targets. As example, depending of the context, the same image could be paste in png, jpg, or whatever else.

    The problem


    The big problem I am facing is I didn’t find a way to have in the same time i) many targets, and ii) a persistent modes.

    With the simple solutions as Xclip, I can set one target at the time and last one overwrite the previous. However, with Qt’s modules, I can get the desired behavior, but this behavior ended when I close the Qt application and goes back to the situation before Qt.

    My tries

    1. Xclip


    xclip -selection clipboard -t image/png -i image.png
    xclip -selection clipboard -t image/jpg -i image.jpg


    When I inspect the clipboard situation, I just find the last one:

    xclip -selection clipboard -t TARGETS -o
    TARGETS
    image/jpg


    Well, basically, Xclip doesn’t support it.

    2. Using Qt


    import base64
    from PyQt5.QtWidgets import QApplication
    from PyQt5.QtGui import QImage, QClipboard
    from PyQt5.QtCore import QMimeData, QByteArray, QBuffer, QIODevice
    import sys

    # Example: load an image in base64 (from a real file here for testing)
    with open("image.png", "rb") as f:
    base64_data = base64.b64encode(f.read()).decode()

    # Decode base64 → bytes
    image_bytes = base64.b64decode(base64_data)

    # Load image into a QImage
    qimage = QImage.fromData(image_bytes)
    if qimage.isNull():
    raise ValueError("Invalid image")

    # Start Qt
    app = QApplication([])

    # Create a QMimeData
    mime_data = QMimeData()

    # Add native image
    mime_data.setImageData(qimage)

    # Add image/png format
    png_bytes = QByteArray()
    buffer = QBuffer(png_bytes)
    buffer.open(QIODevice.WriteOnly)
    qimage.save(buffer, "PNG")
    buffer.close()
    mime_data.setData("image/png", png_bytes)

    # Add image/jpeg format
    jpeg_bytes = QByteArray()
    buffer = QBuffer(jpeg_bytes)
    buffer.open(QIODevice.WriteOnly)
    qimage.save(buffer, "JPEG")
    buffer.close()
    mime_data.setData("image/jpeg", jpeg_bytes)

    # Copy to clipboard
    QApplication.clipboard().setMimeData(mime_data)
    # QApplication.clipboard().setMimeData(mime_data, QClipboard.Clipboard)

    print("Image copied to clipboard with multiple formats.")

    # Optional: keep app alive a bit so clipboard survives
    app.processEvents()
    input("Press Enter to quit...")


    I verify with Xclip and it works:

    % xclip -selection clipboard -t TARGETS -o
    application/x-qt-image
    image/png
    image/jpeg
    image/avif
    image/bmp
    image/bw
    image/cur
    image/eps
    image/epsf
    image/epsi
    image/heic
    image/heif
    image/icns
    image/ico
    image/jpg
    image/jxl
    image/pbm
    BITMAP
    image/pcx
    image/pgm
    image/pic
    image/ppm
    PIXMAP
    image/rgb
    image/rgba
    image/sgi
    image/tga
    image/tif
    image/tiff
    image/wbmp
    image/webp
    image/xbm
    image/xpm
    TARGETS
    MULTIPLE
    TIMESTAMP
    SAVE_TARGETS


    But it works until the app is runing. When I push Enter, the clipboard change.

    Some observations


    Lot of softwares do it. Look at what’s happens when you copy image or text from your browser, or when you copy files from your file browser. So it doesn’t seems to be something particularly exceptional.

    The question


    How to get the same behavior as the Qt solution but with a persistent mode, not depending of the application’s execution?

    Continue reading...

Compartilhe esta Página