PyQtGraph LegendItem偏移值异常及鼠标拖动后位置获取问题
PyQtGraph LegendItem 真实位置获取问题
问题描述
在Qt5窗口中使用PyQtGraph搭建动态场景,支持添加/修改绘图、坐标轴、曲线,图例可显示/隐藏,用户还能通过鼠标拖动图例改变位置,需要存储并恢复图例的位置。但遇到以下问题:
- 调用
setOffset()设置位置生效,但legend.offset属性始终返回初始值 - 用
legend.opts['offset']能获取代码设置的偏移值,但鼠标拖动图例时该值不会变化,查看源码发现拖动修改的是autoAnchor(GraphicsWidgetAnchor对象),不清楚如何获取其数值,是否必须子类化LegendItem并重写mouseDragEvent?
最小可复现代码
import numpy as np import pyqtgraph as pg win = pg.plot() win.setWindowTitle('MWE legend offset') c1 = win.plot([np.random.randint(0,8) for i in range(10)], pen='r', name='curve1') legend = pg.LegendItem((80,60), offset=(70,20)) legend.setParentItem(win.graphicsItem()) legend.addItem(c1, 'curve1') print(f"Before setting an offset: {legend.offset}") # 返回(70,20) legend.setOffset([300,300]) print(f"After setting an offset: {legend.offset}") # 仍返回(70,20) if __name__ == '__main__': pg.exec()
解决方案
不需要子类化LegendItem,可以通过以下方式获取不同场景下的真实位置:
1. 获取代码设置的偏移值
legend.offset属性仅返回初始化时的默认值,而setOffset()实际修改的是opts字典中的offset项,直接访问legend.opts['offset']即可获取代码设置的偏移值。
2. 获取鼠标拖动后的位置
鼠标拖动图例时,PyQtGraph通过调整autoAnchor来改变位置,你可以通过以下两种方法获取真实位置:
- 获取锚点信息:调用
legend.anchor(),返回元组格式为((anchor_x, anchor_y), (offset_x, offset_y)),包含锚点相对位置和偏移量 - 获取绝对坐标:调用
legend.pos(),返回QPointF对象,通过x()和y()方法可获取图例相对于父控件的绝对坐标值
验证示例代码
import numpy as np import pyqtgraph as pg win = pg.plot() win.setWindowTitle('Legend Position Demo') c1 = win.plot([np.random.randint(0,8) for i in range(10)], pen='r', name='curve1') legend = pg.LegendItem((80,60), offset=(70,20)) legend.setParentItem(win.graphicsItem()) legend.addItem(c1, 'curve1') # 打印代码设置的偏移 print(f"初始化偏移值: {legend.opts['offset']}") legend.setOffset([300,300]) print(f"代码修改后的偏移值: {legend.opts['offset']}") # 实时打印拖动后的位置 def print_current_pos(): pos = legend.pos() anchor_info = legend.anchor() print(f"当前绝对位置: ({round(pos.x(),2)}, {round(pos.y(),2)}) | 锚点信息: {anchor_info}") # 每秒打印一次位置,方便验证拖动效果 timer = pg.QtCore.QTimer() timer.timeout.connect(print_current_pos) timer.start(1000) if __name__ == '__main__': pg.exec()
位置存储与恢复
如果需要存储图例位置,直接保存legend.pos().x()和legend.pos().y()的值即可;恢复位置时调用legend.setPos(saved_x, saved_y),比使用offset更直接可靠。
内容的提问来源于stack exchange,提问作者emma
相关产品推荐
相关产品推荐

