我正在使用 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())```
问题是您重写了
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)