如何在PyQt5 GLScatterPlotItem中使用信号实现点击点获取坐标
3D点云点击获取坐标功能实现方案
错误原因
你混淆了pyqtgraph的两类散点控件:
- 你查阅的是2D散点控件
ScatterPlotItem的相关能力,该控件确实提供sigClicked点击信号 - 你代码中实际使用的是OpenGL实现的3D散点控件
GLScatterPlotItem,该控件本身没有内置sigClicked信号,因此抛出AttributeError
另外你原有代码还存在两处语法逻辑错误:
- 信号绑定语句
self.position.sigClicked.connect(self.clicked())中,槽函数加了括号会直接执行函数,传递的是函数返回值而非函数本身,绑定时需要去掉括号 - 槽函数中直接用
+拼接字符串和坐标对象会触发类型错误,需要先做类型转换或者用格式化字符串输出
实现方案
通过给3D视图绑定鼠标事件,自行实现射线拾取逻辑来获取点击的点坐标,完整实现如下:
1. 初始化代码修改
from pyqtgraph.opengl import GLScatterPlotItem, GLViewWidget import numpy as np # 原有3D视图初始化逻辑不变 self.graphtroisd = GLViewWidget() # 你的点云数据,保留原有生成逻辑即可 self.pos = np.random.randn(100, 3) # 建议调大点的显示尺寸,降低拾取难度 self.position = GLScatterPlotItem(pos=self.pos, size=5) self.graphtroisd.addItem(self.position) # 给3D视图绑定鼠标点击事件 self.graphtroisd.mousePressEvent = self.on_3d_view_click
2. 拾取逻辑实现
def on_3d_view_click(self, event): # 先调用父类原有鼠标事件逻辑,不影响默认的视图旋转平移操作 super(GLViewWidget, self.graphtroisd).mousePressEvent(event) # 获取点击位置坐标 click_pos = event.pos() view_w = self.graphtroisd.width() view_h = self.graphtroisd.height() # 转换为标准化设备坐标(范围-1~1) x = 2 * click_pos.x() / view_w - 1 y = 1 - 2 * click_pos.y() / view_h # 获取当前视图的投影矩阵、模型视图矩阵 proj_mat = self.graphtroisd.projectionMatrix() view_mat = self.graphtroisd.viewMatrix() # 计算拾取射线的近、远平面点 def unproject(point): point = np.linalg.inv(proj_mat) @ point point /= point[3] point = np.linalg.inv(view_mat) @ point return point[:3] / point[3] near_p = unproject(np.array([x, y, -1, 1.0])) far_p = unproject(np.array([x, y, 1, 1.0])) ray_dir = far_p - near_p ray_dir /= np.linalg.norm(ray_dir) # 计算所有点到射线的距离 all_points = self.position.pos vec = all_points - near_p[np.newaxis, :] cross_res = np.cross(vec, ray_dir[np.newaxis, :]) dist_list = np.linalg.norm(cross_res, axis=1) # 取距离最近的点,小于阈值视为选中 min_idx = np.argmin(dist_list) # 阈值可根据点大小、点云密度自行调整 if dist_list[min_idx] < 0.2: x, y, z = all_points[min_idx] print(f"点击点坐标:x={x:.3f}, y={y:.3f}, z={z:.3f}")
3. 注意事项
- 拾取阈值可根据实际场景调整,阈值越大越容易选中点,同时误选概率也会升高
- 若点云有额外的缩放、平移、旋转变换,需要将对应变换矩阵加入坐标计算逻辑,保证拾取精度
内容的提问来源于stack exchange,提问作者Pierre-yves Icdc Chaboche
相关产品推荐
相关产品推荐

