python - 如何在 Pyqtgraph 上将平移事件从滚轮按下+拖动更改为鼠标右键单击+拖动?
问题描述
默认情况下,3D可视化鼠标交互pyqtgraph
在[鼠标滚轮按下+拖动]上有平移事件,如何在[鼠标右键+拖动]上设置这样的平移事件?
mousePressEvent
似乎它应该是和mouseMoveEvent
或只是的某种组合eventFilter(self, source, event)
我pyqtgraph
openGLWidget
放在 PyQt5 表单上,所以看起来这样的事件应该openGLWidget
从QMainWindow
类内部继承。
但我不确定如何制作这样的事件过滤器。
一些伪代码初步想法:
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
uic.loadUi(_UI, self)
axis = gl.GLAxisItem()
self.openGLWidget.addItem(axis)
...
...
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.KeyPress):
...
...
return super(openGLWidget, self).eventFilter(source, event)
解决方案
可能是这样的:
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
uic.loadUi(_UI, self) # Load the .ui file
axis = gl.GLAxisItem()
grid = gl.GLGridItem()
grid.scale(100, 100, 100)
self.openGLWidget.addItem(grid)
self.openGLWidget.addItem(axis)
# installEventFilter
self.openGLWidget.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QtCore.QEvent.MouseMove:
if event.buttons() == QtCore.Qt.NoButton:
print("Simple mouse motion")
pass
elif event.buttons() == QtCore.Qt.LeftButton:
# print("Left click drag")
pass
elif event.buttons() == QtCore.Qt.RightButton:
coef = 20 # Responsiveness of the pan
xx = ((self.openGLWidget.size().width())/2)/coef
yy = ((self.openGLWidget.size().height())/2)/coef
self.pan((event.x()/coef)-xx, (event.y()/coef)-yy, 0)
self.openGLWidget.updateGL()
# print("Right click drag")
elif event.type() == QtCore.QEvent.MouseButtonPress:
if event.button() == QtCore.Qt.RightButton:
pass
# print("Press!")
return super(MainWindow, self).eventFilter(source, event)
def pan(self, dx, dy, dz, relative='view'):
"""
Moves the center (look-at) position while holding the camera in place.
============== =======================================================
*relative* String that determines the direction of dx,dy,dz.
If "global", then the global coordinate system is used.
If "view", then the z axis is aligned with the view
If "view-upright", then x is in the global xy plane and
points to the right side of the view, y is in the
global xy plane and orthogonal to x, and z points in
the global z direction.
"""
# for backward compatibility:
relative = {True: "view-upright", False: "global"}.get(relative, relative)
if relative == 'global':
self.openGLWidget.opts['center'] += QtGui.QVector3D(dx, dy, dz)
elif relative == 'view-upright':
cPos = self.openGLWidget.cameraPosition()
cVec = self.openGLWidget.opts['center'] - cPos
dist = cVec.length() ## distance from camera to center
xDist = dist * 2. * np.tan(0.5 * self.openGLWidget.opts['fov'] * np.pi / 180.) ## approx. width of view at distance of center point
xScale = xDist / self.width()
zVec = QtGui.QVector3D(0,0,1)
xVec = QtGui.QVector3D.crossProduct(zVec, cVec).normalized()
yVec = QtGui.QVector3D.crossProduct(xVec, zVec).normalized()
self.openGLWidget.opts['center'] = self.openGLWidget.opts['center'] + xVec * xScale * dx + yVec * xScale * dy + zVec * xScale * dz
elif relative == 'view':
# pan in plane of camera
elev = np.radians(self.openGLWidget.opts['elevation'])
azim = np.radians(self.openGLWidget.opts['azimuth'])
fov = np.radians(self.openGLWidget.opts['fov'])
dist = (self.openGLWidget.opts['center'] - self.openGLWidget.cameraPosition()).length()
fov_factor = np.tan(fov / 2) * 2
scale_factor = dist * fov_factor / self.width()
z = scale_factor * np.cos(elev) * dy
x = scale_factor * (np.sin(azim) * dx - np.sin(elev) * np.cos(azim) * dy)
y = scale_factor * (np.cos(azim) * dx + np.sin(elev) * np.sin(azim) * dy)
self.openGLWidget.opts['center'] += QtGui.QVector3D(x, -y, z)
else:
raise ValueError("relative argument must be global, view, or view-upright")
self.update()
推荐阅读
- python - 如何在 jupyter 实验室中使用已安装的库?
- c# - Unity 2d:游戏对象集活动不适用于父母和所有孩子
- python - sympy lambdify 与元组中的函数参数?
- android - 默认情况下,AWS Pinpoint 在 react native 中选择退出 Android 用户的推送通知
- c++ - 如何检查升压融合序列是否是适应结构?
- react-native - 如何在 package.json 中包含 *forked* github 分支作为依赖项
- html - 如何使用文件应用在 iPhone 上查看结束编辑 html 文件?
- java - 如何解析邮递员收藏?
- docker - 如何在 docker 镜像中安装 @vue/cli
- c# - IntPtr.operator + (IntPtr, int) 不能调用 operator 或 accessor