Search code examples
qtpyqtpyqt5pyqt6

Draw transparent image over the screen with Qt


I'm trying to draw an image with a transparent background over the entire screen. I've done similar with Xlib, but I thought I'd try Qt so my program might work in different environments besides X11. Before getting committed, I've honestly just searched the internet trying to find a working example but failed.

So I've got an image of coordinates that I want to overlay on the screen. The image is a PNG with a transparent background. Here's a picture of what I want to see, my desktop with coordinates: enter image description here

Here's my PyQt6 code, it draws the image fullscreen but sadly you can't see through it, it has a black background:

import sys
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QImage
from PyQt6.QtWidgets import QApplication, QMainWindow

from PyQt6.QtGui import QPainter

class Img(QMainWindow):
    def __init__(self, img_path, parent=None):
        super().__init__(parent)
        self.qimg = QImage(img_path)
        self.setStyleSheet('QMainWindow {background:transparent}')
        self.setWindowFlags(
            Qt.WindowType.WindowStaysOnTopHint |
            Qt.WindowType.FramelessWindowHint |
            Qt.WindowType.WindowTransparentForInput
        )
        self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)

    def paintEvent(self, qpaint_event):
        painter = QPainter(self)
        rect = qpaint_event.rect()
        painter.drawImage(rect, self.qimg)
        self.showFullScreen()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    img_path = 'coords.png'
    window = Img(img_path)
    window.show()
    sys.exit(app.exec())

Answers don't need to be PyQt6, perhaps PyQt5 or written in Go.


Solution

  • I have tried your code and it works fine, apparently it seems to be a problem of the image, I recommend you to use some kind of external application to erase the transparent parts like this.

    Here is a test that works with your code:enter image description here

    If you want to do this automatically I recommend you to use opencv.