如何绘制矩形以提取 Qlabel 小部件中显示的 QImage 的 ROI

问题描述 投票:0回答:1

我创建了一个基于 QWidget 的

AnotherWidget
窗口,其中包含
Qlabel
和其他一些
QLineEdit
来显示 X 和 Y 偏移,还有用于图像矩形选择的宽度和高度。

满足的初始条件是在图像上绘制一个矩形。在 QLabel 中显示图像是成功的,但是当我绘制矩形时,它看起来像是在 Widget 窗口背景上绘制的。这里有几张图片来解释情况。

我一直在开发的小部件窗口:

这张图片

当前绘制矩形时的情况:

这种情况图

鼠标事件和绘画事件都很好,但是它在背景上绘制了矩形! (奇怪,也许我在使用 Qlabel 时错过了一些东西)

我对 PyQt 的所有东西都很陌生,目前在我的 VSCode 环境中使用 PySide6。这是代码


class AnotherWidget(QWidget, Ui_ROIWidget):
    roi_selected = Signal(int,int,int,int)

    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.setWindowTitle("Custom ROI selection")
        self.begin = QPoint()
        self.end = QPoint()

    def paintEvent(self, event):
        super().paintEvent(event)

        qp = QPainter(self)
        br = QBrush(QColor(100, 10, 10, 40))  
        qp.setBrush(br)   
        qp.drawRect(QRect(self.begin, self.end))       

    def mousePressEvent(self, event):
        self.begin = event.pos()
        self.end = event.pos()
        self.update()

    def mouseMoveEvent(self, event):
        self.end = event.pos()
        self.update()

    def mouseReleaseEvent(self, event):
        self.begin = event.pos()
        self.end = event.pos()
        self.rect = QRect(self.start_point, self.end_point).normalized()
        self.update()
        x, y, width, height = self.rect.x(), self.rect.y(), self.rect.width(), self.rect.height()
        self.roi_selected.emit(x, y, width, height)
        self.update()

    @Slot()
    def show_image(self,image):
        self.label.setPixmap(QPixmap.fromImage(image))

这是怎么回事?我在使用 QPainter 的方法定义中是否遗漏了一些内容,或者我应该使用另一个小部件而不是 Qlabel 来显示图像?我该怎么办?

编辑 假设可能需要,我使用 QtDesigner 来调整所有小部件和主窗口,在这里我将

ImageROI
作为捕获的图像信号从相机线程发送到主窗口方法。


class CameraProccess(QThread):
    #Signal type definition 
    Image=Signal(QImage)
    ImageProcess = Signal(QImage)
    ImageCaptured = Signal(QImage)
    ImageROI = Signal(QImage)
    
    [...]

class mainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
       super().__init__()
        self.setupUi(self)
        self.setWindowTitle("Recorder Inspection Monitor V1.0")
        self.resize(1280,800)

        self.ROIwindow = AnotherWidget()
        self.setROIButton.clicked.connect(self.toggle_roiWindow)
 
    [...]
 
    def toggle_roiWindow(self):
        global setROI

        setROI = True

        if self.ROIwindow.isVisible()==False:
            self.Worker1_Opencv.ImageROI.connect(self.ROIwindow.show_image)
            self.ROIwindow.show()
        
        else:
            self.Worker1_Opencv.ImageROI.connect(self.ROIwindow.show_image)
python qt pyqt pyside6 roi
1个回答
0
投票

不。您应该使用

QRubberBand
类而不是
paintEvent

paintEvent 在 widget 本身上进行绘制(准确地说,widget 就是 PaintDevice。)

您将图像放在设备上,因此无法在图像上绘制矩形。您不小心在小部件上绘图,因此图像隐藏了矩形。

由于没有完整的最小示例代码,我提交了使用

QRubberband
的演示。

请删除

paintEvent
的代码。

您可以获取有关如何使用的信息

QRubberBand

Qt 文档 - QRubberBand

PySide6:

from PySide6.QtWidgets import QWidget, QApplication, QRubberBand
from PySide6.QtGui import QPainter, QBrush, QColor, QPixmap
from PySide6.QtCore import Signal, Slot, QPoint, QRect

class AnotherWidget(QWidget ):
    roi_selected = Signal(int,int,int,int)

    def __init__(self):
        super().__init__()

        self.setWindowTitle("Custom ROI selection")
        self.begin = QPoint()
        self.end = QPoint()
        self.rubberBand = QRubberBand(QRubberBand.Shape.Rectangle, self)
    def paintEvent(self, event):
        super().paintEvent(event)
 

    def mousePressEvent(self, event):
        self.begin = event.position().toPoint()
        self.end = event.position().toPoint()
        rect = QRect()
        rect.setCoords(self.begin.x(), self.begin.y(), self.end.x(), self.end.y())
        self.rubberBand .setGeometry(rect)
        self.rubberBand.show()
  
        self.update()

    def mouseMoveEvent(self, event):
        self.end = event.position().toPoint()
        rect = QRect()
        rect.setCoords(self.begin.x(), self.begin.y(), self.end.x(), self.end.y())    
        self.rubberBand .setGeometry(rect)
        self.update()

    def mouseReleaseEvent(self, event):
        self.begin = event.position().toPoint()
        self.end = event.position().toPoint()
        rect = QRect()
        rect.setCoords(self.begin.x(), self.begin.y(), self.end.x(), self.end.y())
        self.rubberBand .setGeometry(rect)

        self.update()
        x, y, width, height = rect.x(), rect.y(), rect.width(), rect.height()
        self.roi_selected.emit(x, y, width, height)
        self.update()
        self.rubberBand.close()

    @Slot()
    def show_image(self,image):
        self.label.setPixmap(QPixmap.fromImage(image))

def main():
        import sys
        app = QApplication()
        w = AnotherWidget()
        w.show()
        sys.exit(app.exec())
        
if __name__ == "__main__":
    main()
© www.soinside.com 2019 - 2024. All rights reserved.