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?