Wednesday, 2 October 2019

PyQt5 Make a fullscreen paint program with no background

My goal is to make a little PC/Windows program which will allow me to literally draw on top of my screen and save the result as png with transparent background. Like softwares like Epic Pen or gInk but my way. All using Python 3.7 and PyQt5.

So far, I managed to get a functional drawing app (basically following this tutorial) because I'm learning PyQt at the same time. I managed to save my drafts as png with transparent background. I can make the drawing board fullscreen and borderless.

Now the issue is, I can't find a way to make the whole background transparent. Though I've found ways to make a window transparent and borderless using these:

Window = Window()
Window.setStyleSheet("background:transparent;")
Window.setAttribute(Qt.WA_TranslucentBackground)
Window.setWindowFlags(Qt.FramelessWindowHint)
Window.show()

And it works... Until I have a drawing area. I can draw on it, it will save with a transparent background, but it displays black.

So I'm searching for that solution. Even without PyQt, I don't really care, as long as I can make my program work.

So here is what I have (I show you windowed with the frame to make it easier to explain): enter image description here

And here is what I want: enter image description here

And here is my code:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenuBar, QMenu, QAction, QShortcut, QFileDialog
from PyQt5.QtGui import QIcon, QImage, QPainter, QPen
from PyQt5.QtCore import Qt, QPoint


class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        top = 400
        left = 400
        width = 800
        height = 600

        icon = "icons/icon.png"

        self.setWindowTitle("ScreenPen drawing board")
        self.setGeometry(top, left, width, height)
        self.setWindowIcon(QIcon(icon))

# ---------- sets image ----------
        self.image = QImage(self.size(), QImage.Format_RGBA64)
        self.image.fill(Qt.transparent)

# ---------- init drawing state ----------
        self.drawing = False
        self.brushSize = 2
        self.brushColor = Qt.red
        self.lastPoint = QPoint()

# ---------- Define Menus ----------
    # mainmenu
        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu("File")
        toolMenu = mainMenu.addMenu("Tool")
        toolColor = mainMenu.addMenu("Color")
    # smenu save
        saveAction = QAction(QIcon("icons/save.png"), "Save", self)
        saveAction.setShortcut("Ctrl+S")
        fileMenu.addAction(saveAction)
        saveAction.triggered.connect(self.saveFrame)
    # smenu clear frame
        clearFrameAction = QAction(QIcon("icons/clear.png"), "Clear Frame", self)
        clearFrameAction.setShortcut("Ctrl+Del")
        fileMenu.addAction(clearFrameAction)
        clearFrameAction.triggered.connect(self.clearFrame)
    # smenu Tool Pen
        toolPenAction = QAction(QIcon("icons/toolPen.png"), "Pen", self)
        # clearAction.setShortcut("Ctrl+Del")
        toolMenu.addAction(toolPenAction)

# ---------- Catch Mouse Down --------

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drawing = True
            self.lastPoint = event.pos()

# ---------- Catch Mouse Move --------
    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) & self.drawing:
            painter = QPainter(self.image)
            painter.setPen(QPen(self.brushColor, self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
            painter.drawLine(self.lastPoint, event.pos())
            self.lastPoint = event.pos()
            self.update()

# ---------- Catch Mouse Up --------
    def mouseReleaseEvent(self, event):
        if event.button == Qt.LeftButton:
            self.drawing = False

# ---------- Paint --------
    def paintEvent(self, event):
        canvasPainter = QPainter(self)
        canvasPainter.drawImage(self.rect(), self.image, self.image.rect())

# ---------- Save Action ----------
    def saveFrame(self):
        filePath,  _ = QFileDialog.getSaveFileName(self, "Save Image", "", "PNG(*.png);;JPEG(*.jpg *.jpeg);; ALL Files(*.*)")
        if filePath == "":
            return
        self.image.save(filePath)

# ---------- Clear Frame Action ----------
    def clearFrame(self):
        self.image.fill(Qt.white)
        self.update()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    Window = Window()
    # Window style
    Window.setStyleSheet("background:transparent;")
    Window.setAttribute(Qt.WA_TranslucentBackground)
    # Window.setWindowFlags(Qt.FramelessWindowHint)
    Window.show()
    app.exec()


from PyQt5 Make a fullscreen paint program with no background

No comments:

Post a Comment