Прозрачное окно поверх остальных, с обновляемым(и) прямоугольником

У меня есть координаты прямоугольника которые я получаю из opencv:

x, y, w, h (x и y это верхний левый угол, w - ширина прямоугольника и h - высота)

 x
y ------
 |      |
 |      | h
 |      |
  ------
     w

Мне нужно отображать в центре экрана полностью прозрачное окно которое будет по верх полноэкранного, и которое будет получать значения x, y, w, h, и отображать их в виде прямоугольника (Например красным цветом)

Вот небольшой пример кода, где нужен будет этот функционал:

def getcoord(p_in):
    import numpy as np
    last = True #Я не могу показать пример с ограничением в 60фпс, т.к. этот пример вы не сможете проверить.
    while True:
        if last == True:
            last = False
            coord = np.array([15, 15, 50, 50]) # я получаю немного иначе координаты, но и этот вариант пойдёт.
        else:
            last = True
            coord = np.array([15, 15, 25, 25])
        p_in.send(coord)

def drawcoord(p_out):
    import cv2
    while True:
        coord = p_out.recv()
        x,y,w,h = coord
        print("x -", x, "y - ", y,"w - ", w ,"h -", h)
        #cv2.rectangle(img, (x, y),(x+w, y+h), (0, 0, 255), 1) здесь как то он должен был рисовать прямоугольники

if __name__=="__main__":
    import multiprocessing
    p_out, p_in = multiprocessing.Pipe()#вот тут, если закрыть p1, то p2 не будет работать.
    p1 = multiprocessing.Process(target=getcoord, args=(p_in,))
    p2 = multiprocessing.Process(target=drawcoord, args=(p_out,))
    p2.start()
    p1.start()

Я пытался использовать opencv, но он не знает что такое прозрачность, и он не производительный т.к. он будет получать 60 значений в секунду, и их Нужно отображать на экране в 60 кадров/сек (А то и больше!)

Координаты прямоугольников будут передаваться в multiprocessing, через multiprocessing.Pipe(), поэтому когда он не будет получать значения, на экране ничего не должно быть. То есть, что когда значение не получено, то прямоугольник просто останется на месте, вместо того что бы исчезнуть (Т.к. если нет переменных в очереди Pipe, то процесс как я понял не работает) Можно попробовать передавать пустые данные, что бы сообщить что экран должен быть пустой.

Также один раз будете передана переменная, которая указывает на размер этого прозрачного окна (Допустим 100 пикселей в ширину и в высоту)

Вот неплохой пример того, как это будет использоваться:

https://youtu.be/7oa0XGfWyy4?t=6

p.s это наверное слишком сложно xD, поэтому простите.


Ответы (1 шт):

Автор решения: S. Nick

Вариант того, что вы хотите сделать используя PyQt5, предоставлен ниже. Нажмите кнопку и перетаскивайте ее, а затем отпустите.

Вам надо вставить свою реализацию получения координат вместо методов mousePressEvent, mouseMoveEvent, mouseReleaseEvent и вызвать self.draw().

К сожалению, я не понял как вы это делаете в предоставленном вами коде. Но это уже совсем другая история.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.label = QtWidgets.QLabel()
        self.setCentralWidget(self.label)

        self.main_pixmap = QtGui.QPixmap("background.png")  
        self.aim_pixmap = QtGui.QPixmap("_+_.png")
        self.start = QtCore.QPoint(-80, 0)
        self.draw()

    def draw(self):
        pixmap = self.main_pixmap.copy()
        painter = QtGui.QPainter(pixmap)
        painter.setRenderHints(
            QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform
        )
        painter.translate(self.start)
        painter.drawPixmap(QtCore.QPoint(), self.aim_pixmap)
        painter.end()
        self.label.setPixmap(pixmap)
        
    def mousePressEvent(self, event):
        self.start = event.pos() - QtCore.QPoint(40, 40)
        self.draw()

    def mouseReleaseEvent(self, event):
        self.start = QtCore.QPoint(-80, 0)
        self.draw()

    def mouseMoveEvent(self, event):
        self.start = event.pos() - QtCore.QPoint(40, 40)
        self.draw()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения


_+_.png

введите сюда описание изображения

→ Ссылка