我创建了一个基于 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)
不。您应该使用
QRubberBand
类而不是 paintEvent
。
paintEvent 在 widget 本身上进行绘制(准确地说,widget 就是 PaintDevice。)
您将图像放在设备上,因此无法在图像上绘制矩形。您不小心在小部件上绘图,因此图像隐藏了矩形。
由于没有完整的最小示例代码,我提交了使用
QRubberband
的演示。
请删除
paintEvent
的代码。
您可以获取有关如何使用的信息
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()