【问题标题】:How can I change mousewheel behaviour in PyQtGraph ImageView?如何更改 PyQtGraph ImageView 中的鼠标滚轮行为?
【发布时间】:2021-05-19 10:06:48
【问题描述】:

我正在使用 ImageView 显示 3D 体积的 2D 切片(MRI 扫描数据),并希望更改鼠标绑定以使用户更直观。默认情况下,鼠标滚轮更改图像比例/缩放。相反,我希望轮子切换到下一个/上一个切片 - 沿着构成 3D 体积的一系列 2D 图像向前或向后移动。文档使用 z 轴作为时间 - 所以它会及时向前/向后移动。

我没有看到任何简单的 pyqtgraph 鼠标事件方法可以重新实现,也看不到如何在 PySide2 中执行此操作。这个虚函数grabMouseEvent()好像有提示但是不知道怎么重新实现来抓轮子。

这是我创建窗口和 50 帧 100x100 像素噪声数据的最小工作代码:

from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QMainWindow
from PySide2.QtWidgets import QWidget
from PySide2.QtWidgets import QHBoxLayout

import pyqtgraph as pg
import numpy as np
import sys


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.cw = QWidget(self)
        self.cw.setAutoFillBackground(True)
        self.setCentralWidget(self.cw)

        self.layout = QHBoxLayout()
        self.cw.setLayout(self.layout)

        self.DcmImgWidget = MyImageWidget(parent=self)
        self.layout.addWidget(self.DcmImgWidget)

        self.show()


class MyImageWidget(pg.ImageView):
    def __init__(self, parent):
        super().__init__()

        self._parent = parent
        self.ui.histogram.hide()
        self.ui.roiBtn.hide()
        self.ui.menuBtn.hide()

        # 50 frames of 100x100 random noise
        img = np.random.normal(size=(50, 100, 100))
        self.setImage(img)


def main():
    app = QApplication(sys.argv)
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

使用图片下方的滚动条可以很好地滚动。

如何在 PyQtGraph 对象中重新实现鼠标滚轮事件?

【问题讨论】:

    标签: python pyside2 pyqtgraph


    【解决方案1】:

    一种可能的解决方案是通过事件过滤器拦截GraphicsView的wheel事件,阻止该事件被传递,然后利用事件信息发出一个信号,指示是转到下一页还是上一页。

    import sys
    
    from PySide2.QtCore import QObject, QEvent, Signal
    from PySide2.QtWidgets import (
        QApplication,
        QHBoxLayout,
        QMainWindow,
        QWidget,
    )
    
    import pyqtgraph as pg
    import numpy as np
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            self.DcmImgWidget = MyImageWidget()
    
            self.cw = QWidget()
            self.cw.setAutoFillBackground(True)
            self.setCentralWidget(self.cw)
    
            layout = QHBoxLayout(self.cw)
            layout.addWidget(self.DcmImgWidget)
    
    
    class Helper(QObject):
        changed = Signal(bool)
    
        def __init__(self, widget):
            super().__init__(widget)
            self._widget = widget
            self.widget.installEventFilter(self)
    
        @property
        def widget(self):
            return self._widget
    
        def eventFilter(self, obj, event):
            if obj is self.widget and event.type() == QEvent.Wheel:
                self.changed.emit(event.angleDelta().y() > 0)
                return True
    
            return super().eventFilter(obj, event)
    
    
    class MyImageWidget(pg.ImageView):
        def __init__(self, parent=None):
            super().__init__(parent)
            self.ui.histogram.hide()
            self.ui.roiBtn.hide()
            self.ui.menuBtn.hide()
    
            # 50 frames of 100x100 random noise
            img = np.random.normal(size=(50, 100, 100))
            self.setImage(img)
    
            gv = self.ui.graphicsView
            helper = Helper(gv.viewport())
            helper.changed.connect(self.change_page)
    
        def change_page(self, state):
            self.jumpFrames(1 if state else -1)
    
    
    def main():
        app = QApplication(sys.argv)
        main = MainWindow()
        main.show()
        sys.exit(app.exec_())
    
    
    if __name__ == "__main__":
        main()
    

    【讨论】:

    • 谢谢!我花了一段时间才看到你在那里做了什么 - 让我检查一下我的理解 - 辅助函数创建一个新信号'changed',当鼠标滚轮事件到达'eventFilter'时使用它。 'self.changed.emit' 然后将'(event.angleDelta().y() > 0)' 的布尔结果作为参数传递给连接的'change_page' 方法。因此,为了捕获和处理鼠标点击和拖动,我假设我应该在“MyImageWidget”中创建一个新信号、eventFilter 条件和相应的插槽方法......?
    猜你喜欢
    • 2016-04-20
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 2017-09-03
    • 2020-08-05
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    相关资源
    最近更新 更多