如何根据 PyQt6 和 Pyqtgraph 悬停的项目来更改鼠标行为?

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

我正在使用 PyQt6 和 PyQtGraph 创建 DICOM 图像可视化界面。我使用

ImageContainer
类(
pg.ImageView
的子类)显示图像。我使用
mousePressEvent
mouseMoveEvent
修改了单击期间的鼠标行为。我还使用
eventFilter
显示鼠标悬停的像素值,无需单击。

我允许用户使用

CustomEllipseROI
类(
pg.EllipseROI
的子类)添加椭圆形感兴趣区域 (ROI)。默认情况下,ROI 是可移动和可调整大小的,但由于我修改了
ImageContainer
实例的鼠标行为,它不再起作用。

我尝试在

CustomEllipseROI
类中实现另一个 eventFilter,但失败了。

问题: 如何再次启用 ROI 的移动和大小调整,甚至专门针对 ROI 自定义鼠标行为?

这是一个最小的可重现示例。感谢您的帮助!

import sys
import pyqtgraph as pg
import numpy as np

from PyQt6.QtWidgets import QApplication
from PyQt6.QtCore import Qt, QEvent

class CustomEllipseROI(pg.EllipseROI):
    def __init__(self, pos, size, **args):
        super().__init__(pos, size, **args)
   
    def hoverEvent(self, event):
        print("Hover ROI")

class ImageContainer(pg.ImageView):
    def __init__(self, parent = None):
        super().__init__(parent)
        self.create_data()
        self.init_image()
        self.create_ROI()

    def create_data(self):
        dataRed = np.ones((100, 200, 200)) * np.linspace(90, 150, 100)[:, np.newaxis, np.newaxis]
        dataRed += pg.gaussianFilter(np.random.normal(size=(200, 200)), (5, 5)) * 100
        dataGrn = np.ones((100, 200, 200)) * np.linspace(90, 180, 100)[:, np.newaxis, np.newaxis]
        dataGrn += pg.gaussianFilter(np.random.normal(size=(200, 200)), (5, 5)) * 100
        dataBlu = np.ones((100, 200, 200)) * np.linspace(180, 90, 100)[:, np.newaxis, np.newaxis]
        dataBlu += pg.gaussianFilter(np.random.normal(size=(200, 200)), (5, 5)) * 100
        self.data = np.concatenate(
            (dataRed[:, :, :, np.newaxis], dataGrn[:, :, :, np.newaxis], dataBlu[:, :, :, np.newaxis]), axis=3
        )

    def init_image(self):
        self.setImage(self.data)
        self.ui.histogram.hide()
        self.ui.roiBtn.hide()
        self.ui.menuBtn.hide()
        self.ui.roiPlot.hide()

        self.setAttribute(Qt.WidgetAttribute.WA_Hover)
        self.installEventFilter(self)

        self.view.mousePressEvent = self.mouse_press_event
        self.view.mouseMoveEvent = self.mouse_move_event

    def create_ROI(self):
        self.ellipseROI_item = CustomEllipseROI((50, 50), (50, 50))
        self.view.addItem(self.ellipseROI_item)

    def eventFilter(self, obj, event):
        if event.type() == QEvent.Type.HoverMove:
            print("Hover Image")
            # Call function that displays the image value at mouse position
        elif event.type() == QEvent.Type.HoverLeave:
            print("Leave Image")
            # Clear value display
        return super().eventFilter(obj, event)
    
    def mouse_press_event(self, event):
        self.prevPos = event.pos()

    def mouse_move_event(self, event):
        if event.buttons() == Qt.MouseButton.MiddleButton:
            print("Middle Button on Image")
            # Call function to change contrast
        elif event.buttons() == Qt.MouseButton.LeftButton:
            print("Left Button on Image")
            # Call function to move across slices of a volume
        elif event.buttons() == Qt.MouseButton.RightButton:
            print("Right Button on Image")
            # Call function to zoom in/out

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = ImageContainer()
    main.show()
    sys.exit(app.exec())```
python pyqt mouseevent pyqtgraph eventfilter
1个回答
0
投票

问题是您重写了

self.view.mousePressEvent
方法而不调用原始方法。最佳实践是通过调用您要重写的任何方法的原始方法来返回。

我的解决方案添加了对

self.view.mousePressEvent
self.view.mouseMoveEvent
的返回调用,因为这是最佳实践,但该错误仅因
self.view.mousePressEvent
而发生。

class ImageContainer(pg.ImageView)

    def init_image(self):
        # Other stuff.. .

        self.original_view_mouse_press_event = self.view.mousePressEvent
        self.original_view_mouse_move_event = self.view.mouseMoveEvent
        self.view.mousePressEvent = self.mouse_press_event
        self.view.mouseMoveEvent = self.mouse_move_event
    
    
    def mouse_press_event(self, event):
        self.prevPos = event.pos()
        return self.original_view_mouse_press_event(event)
    
    def mouse_move_event(self, event):
        if event.buttons() == Qt.MouseButton.MiddleButton:
            print("Middle Button on Image")
            # Call function to change contrast
        elif event.buttons() == Qt.MouseButton.LeftButton:
            print("Left Button on Image")
            # Call function to move across slices of a volume
        elif event.buttons() == Qt.MouseButton.RightButton:
            print("Right Button on Image")
            # Call function to zoom in/out
        return self.original_view_mouse_move_event(event)
© www.soinside.com 2019 - 2024. All rights reserved.