【问题标题】:pyqtgraph mouse interaction: using mouse right or middle button to zoom to the selected boxpyqtgraph鼠标交互:使用鼠标右键或中键缩放到选中框
【发布时间】:2021-03-31 16:21:17
【问题描述】:

pyqtgraph examples -> View Box Freatures中,我们可以通过设置v2.setMouseMode(v2.RectMode)来使用鼠标交互“左拖动缩放到框”

但这种交互仅在单键鼠标模式下可用。如何修改交互,以便在标准的三键鼠标模式下使用鼠标右键或鼠标中键放大到选定的框?

谢谢大家!

【问题讨论】:

  • 我不明白你的问题,因为在两种模式(PanMode 和 RectMode)下,鼠标右键的工作方式相同,而左鼠标的工作方式与中鼠标相同。那么不同的是:在PanMode中,鼠标左键和中键用于拖动;在 RectMode 中,鼠标左键和中键用于缩放框。见:pyqtgraph.readthedocs.io/en/latest/_modules/pyqtgraph/…
  • @AlejandroCondori 您好,要求完全是在 PanMode 中使用鼠标中键缩放框。默认情况下,缩放框仅在 RectMode 中。所以我想我需要修改viewbox
  • 完美,我在想你会想要鼠标中键和左键分开的功能,而且,正如你所说,你需要修改 viewbox 类。我会把我的代码放在下面。

标签: python pyqt pyqt5 pyside2 pyqtgraph


【解决方案1】:

pyqtgraphViewBox 类只有两种“鼠标模式”:

  • PanMode:鼠标左键和中键用于拖动。鼠标右键可通过拖动放大/缩小。
  • RectMode:鼠标左键和中键用于缩放框。鼠标右键可通过拖动放大/缩小。

鼠标左键和中键的作用相同的原因在于ViewBox类的源代码。 您希望鼠标左键拖动图片,鼠标中键缩放框,鼠标中键缩放框以通过拖动放大/缩小。我的解决方案可能是激进的,但它确实有效。我修改了类,以源代码为模型(来源:Pyqtgraph's ViewBox class):

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np

class ViewBox(pg.ViewBox):
    MyMode = 2
    def __init__(self):
        pg.ViewBox.__init__(self)
        
    def setMouseMode(self, mode):
        ## First we change this method to accept our new configuration
        if mode not in [ViewBox.PanMode, ViewBox.RectMode, ViewBox.MyMode]:
            raise Exception("Mode must be ViewBox.PanMode, ViewBox.RectMode or ViewBox.MyMode")
        self.state['mouseMode'] = mode
        self.sigStateChanged.emit(self)

    def mouseDragEvent(self, ev, axis=None):
        ev.accept()
        pos = ev.pos()
        lastPos = ev.lastPos()
        dif = pos - lastPos
        dif = dif * -1
        mouseEnabled = np.array(self.state['mouseEnabled'], dtype=np.float)
        mask = mouseEnabled.copy()
        if axis is not None:
            mask[1-axis] = 0.0

        ## Here is the main change for it to work    
        if ev.button() & QtCore.Qt.LeftButton:
            if self.state['mouseMode'] == ViewBox.RectMode and axis is None:
                if ev.isFinish():  ## This is the final move in the drag; change the view scale now
                    #print "finish"
                    self.rbScaleBox.hide()
                    ax = QtCore.QRectF(QtCore.QPointF(ev.buttonDownPos(ev.button())), QtCore.QPointF(pos))
                    ax = self.childGroup.mapRectFromParent(ax)
                    self.showAxRect(ax)
                    self.axHistoryPointer += 1
                    self.axHistory = self.axHistory[:self.axHistoryPointer] + [ax]
                else:
                    ## update shape of scale box
                    self.updateScaleBox(ev.buttonDownPos(), ev.pos())
            else:
                tr = self.childGroup.transform()
                tr = pg.functions.invertQTransform(tr)
                tr = tr.map(dif*mask) - tr.map(QtCore.QPointF(0,0))
                x = tr.x() if mask[0] == 1 else None
                y = tr.y() if mask[1] == 1 else None
                self._resetTarget()
                if x is not None or y is not None:
                    self.translateBy(x=x, y=y)
                self.sigRangeChangedManually.emit(self.state['mouseEnabled'])
        elif ev.button() & QtCore.Qt.MidButton:
            if self.state['mouseMode'] in {ViewBox.RectMode,ViewBox.MyMode} and axis is None:
                if ev.isFinish():  ## This is the final move in the drag; change the view scale now
                    #print "finish"
                    self.rbScaleBox.hide()
                    ax = QtCore.QRectF(QtCore.QPointF(ev.buttonDownPos(ev.button())), QtCore.QPointF(pos))
                    ax = self.childGroup.mapRectFromParent(ax)
                    self.showAxRect(ax)
                    self.axHistoryPointer += 1
                    self.axHistory = self.axHistory[:self.axHistoryPointer] + [ax]
                else:
                    ## update shape of scale box
                    self.updateScaleBox(ev.buttonDownPos(), ev.pos())
            else:
                tr = self.childGroup.transform()
                tr = pg.functions.invertQTransform(tr)
                tr = tr.map(dif*mask) - tr.map(QtCore.QPointF(0,0))
                x = tr.x() if mask[0] == 1 else None
                y = tr.y() if mask[1] == 1 else None
                self._resetTarget()
                if x is not None or y is not None:
                    self.translateBy(x=x, y=y)
                self.sigRangeChangedManually.emit(self.state['mouseEnabled'])
        elif ev.button() & QtCore.Qt.RightButton:
            if self.state['aspectLocked'] is not False:
                mask[0] = 0
            dif = ev.screenPos() - ev.lastScreenPos()
            dif = np.array([dif.x(), dif.y()])
            dif[0] *= -1
            s = ((mask * 0.02) + 1) ** dif
            tr = self.childGroup.transform()
            tr = pg.functions.invertQTransform(tr)
            x = s[0] if mouseEnabled[0] == 1 else None
            y = s[1] if mouseEnabled[1] == 1 else None
            center = QtCore.QPointF(tr.map(ev.buttonDownPos(QtCore.Qt.RightButton)))
            self._resetTarget()
            self.scaleBy(x=x, y=y, center=center)
            self.sigRangeChangedManually.emit(self.state['mouseEnabled'])

我们继承Pyqtgraph的ViewBox类,然后改两个方法:

  • setMouseMode() 兼容性
  • mouseDragEvent 3次点击的不同功能

在上面的类中,您保持其他两种鼠标模式不变,但添加了一个新模式:MyMode

然后不要像这样添加ViewBox

sub2 = win.addLayout()
sub2.addLabel("<b>One-button mouse interaction:</b><br>left-drag zoom to box, wheel to zoom out.")
sub2.nextRow()
v2 = sub2.addViewBox()
v2.setMouseMode(v2.RectMode)
l2 = pg.PlotDataItem(y)
v2.addItem(l2)

你应该这样做:

sub2 = win.addLayout()
sub2.addLabel("<b>One-button mouse interaction:</b><br>left-drag zoom to box, wheel to zoom out.")
sub2.nextRow()
v2 = ViewBox() ## This is our new class
sub2.addItem(v2)
v2.setMouseMode(v2.MyMode) ## Seting the new Mouse Mode
l2 = pg.PlotDataItem(y)
v2.addItem(l2)

我测试了代码并没有发现任何问题,但我不得不承认解决方案有点夸张。希望有更简单的方法。

编辑:示例取自Pyqtgraph's examples(ViewBox Features)(Here)

【讨论】:

  • 不错的解决方案。非常感谢
猜你喜欢
  • 1970-01-01
  • 2020-06-16
  • 1970-01-01
  • 2010-10-13
  • 1970-01-01
  • 2012-10-17
  • 2021-07-11
  • 2014-05-06
  • 1970-01-01
相关资源
最近更新 更多