Create a transparent drawing window on top of all applications

Step 1: Introduction

In our modern time, more and more people are faced with the need to create applications or scripts that run on top of other applications without interrupting the user’s work. One interesting example is the creation of a transparent drawing window that allows users to take notes, comments or draw on top of any active window without switching to other applications. I write code that finds and circles certain objects right at work.

In this article, we will look at how to create a transparent drawing window in Python using the PyQt5 library. We will learn how to create a window, adjust its transparency and display it on top of all windows on the desktop, while maintaining functionality and usability for users.

To create a transparent window, we will use the powerful tools provided by the PyQt5 library.

Step 2: Installing the Required Libraries

To create a transparent window, we will use the PyQt5 library, which provides powerful tools for creating a GUI based on Qt.

To install the libraries, you can use the pip command:

pip install PyQt5

or

pip install pyqt5-tools

Step 3: Import the required modules

Once the libraries are installed, we can import them into our code:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtGui import QPainter, QBrush, QColor, QPen
from PyQt5.QtCore import Qt, QTimer, QRect
import random

Step 4: Defining the DrawingWindow Class

To create a transparent window, we define a DrawingWindow class that inherits from the QMainWindow class. The class constructor sets the necessary window parameters, such as title, geometry, and flags. It also initializes the QPainter object to draw on the window.

class DrawingWindow(QMainWindow):
    def __init__(self, coordinates):
        super().__init__()

        # Устанавливаем заголовок окна
        self.setWindowTitle("Прозрачное окно для рисования")

        # Устанавливаем геометрию окна, чтобы оно занимало весь экран
        self.setGeometry(0, 0, QApplication.desktop().screenGeometry().width(),
                         QApplication.desktop().screenGeometry().height())

        # Устанавливаем флаги, чтобы окно было без рамки и оставалось поверх других окон
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowSt

aysOnTopHint)

        # Создаем объект QPainter для рисования на окне
        self.painter = QPainter()
        self.painter.setRenderHint(QPainter.Antialiasing)

        # Устанавливаем начальный цвет пера (красный) и ширину пера (4 пикселя)
        self.pen_color = QColor(255, 0, 0)
        self.pen_width = 4

        # Сохраняем переданные координаты прямоугольников для рисования
        self.coordinates = coordinates

        # Создаем таймер для обновления окна
        self.draw_timer = QTimer()

        # Запускаем таймер и устанавливаем интервал обновления окна (10 миллисекунд)
        self.draw_timer.start(10)

Step 5: Update and Display the Window

In the paintEvent function, the window is updated on each paintEvent event. We use the QPainter object to draw on the window. First the transparent background is drawn, then the rectangles are drawn using the coordinates from the self.coordinates variable.

def paintEvent(self, event):
    self.painter.begin(self)

    # Устанавливаем прозрачный фон
    self.painter.setPen(Qt.NoPen)
    self.painter.setBrush(QBrush(Qt.transparent))
    self.painter.drawRect(QRect(0, 0, self.width(), self.height()))

    # Устанавливаем цвет пера и его ширину
    self.painter.setPen(QPen(QColor(self.pen_color), self.pen_width))
    self.painter.setBrush(QBrush(Qt.transparent))

    # Рисуем прямоугольники, используя переданные координаты
    for coord in self.coordinates:
        x, y, width, height = coord
        self.painter.drawRect(x, y, width, height)

    self.painter.end()

    # Обновляем координаты
    self.update_coord()

    # Планируем перерисовку через 1 секунду
    QTimer.singleShot(1000, self.update)

Step 6: Update Coordinates

The coordinates of the rectangles are updated by calling the update_coord() method, which receives the new coordinates using the R.run() function from the ScreenCapture module. If the new coordinates are presented as a list, then they are stored in the self.coordinates variable. Otherwise, the new coordinates are converted to a list and saved.

def update_coord(self):
    self.coordinates = [(random.randrange(0, 1000), random.randrange(0, 1000), random.randrange(0, 1000)), (random.randrange(0, 1000), random.randrange(0, 1000), random.randrange(0, 1000))]

Step 7: Launching the Application

At startup, the initial coordinates of the s_coordinates rectangles are determined. Then an instance of the Recognizer class is created and a DrawingWindow window is created, passing in the s_coordinates coordinates. The window is then displayed using the show() method.

if __name__ == "__main__":
    # Начальные координаты прямоугольников
    s_coordinates = [(524, 474, 84, 64), (524, 367, 84, 47)]

    app = QApplication(sys.argv)

    # Создаем экземпляр класса Recognizer
    

    # Создаем экземпляр класса DrawingWindow с передачей координат
    window = DrawingWindow(s_coordinates)

    # Отображаем окно
    window.show()

    # Запускаем цикл обработки событий приложения и выходим, когда цикл завершится
    sys.exit(app.exec_())

Now you know how to create a transparent drawing window on top of all applications using the PyQt5 Python library. This can be useful when creating applications or scripts that require user interaction without interrupting their work. If you have any additional questions, feel free to ask them.

The result of the work

As you can see, the quads are perfectly displayed on top of Pycharm and at the same time do not interfere with working with it. In general, this case is part of a project that you can follow here

PUMOVETZ/The-Fool-Game (github.com)

Here is the complete code

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtGui import QPainter, QBrush, QColor, QPen
from PyQt5.QtCore import Qt, QTimer, QRect
import random


class DrawingWindow(QMainWindow):
    def __init__(self, coordinates):
        super().__init__()
        self.setWindowTitle("Transparent Drawing Window")
        self.setGeometry(0, 0, QApplication.desktop().screenGeometry().width(),
                         QApplication.desktop().screenGeometry().height())
        self.setAttribute(Qt.WA_TranslucentBackground, True)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)

        self.painter = QPainter()
        self.painter.setRenderHint(QPainter.Antialiasing)

        self.pen_color = QColor(255, 0, 0)  # Set the initial pen color to red
        self.pen_width = 4  # Set the initial pen width to 4

        self.coordinates = coordinates  # Store the coordinates for drawing rectangles

        self.draw_timer = QTimer()

        self.draw_timer.start(10)  # Update the window every 10 milliseconds

    def paintEvent(self, event):
        self.painter.begin(self)
        self.painter.setPen(Qt.NoPen)
        self.painter.setBrush(QBrush(Qt.transparent))
        self.painter.drawRect(QRect(0, 0, self.width(), self.height()))  # Draw a transparent background

        self.painter.setPen(QPen(QColor(self.pen_color), self.pen_width))
        self.painter.setBrush(QBrush(Qt.transparent))

        for coord in self.coordinates:
            x, y, width, height = coord
            self.painter.drawRect(x, y, width, height)  # Draw rectangles using the provided coordinates

        self.painter.end()

        self.update_coord()  # Update the coordinates
        QTimer.singleShot(1000, self.update)  # Schedule a repaint after 1 second

    def update_coord(self, coords=0):
        if coords != 0:
            pass
        else:
            self.coordinates = [
            (random.randrange(0, 500), random.randrange(0, 500), random.randrange(0, 500), random.randrange(0, 500))]


if __name__ == "__main__":
    coordinates = [(524, 474, 818-524, 689-474), (524, 367, 818-524, 473-367)]

    app = QApplication(sys.argv)

    window = DrawingWindow(coordinates)  # Create an instance of the DrawingWindow class with the given coordinates
    window.show()  # Display the window

    sys.exit(app.exec_())  # Start the application event loop and exit when it's finished

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *