如何在Qt Designer提升的PlotWidget中实现鼠标十字追踪线
嘿,这个问题我之前也碰到过!其实核心原因很简单:PlotWidget是包裹着PlotItem的Qt容器控件,而示例里直接用的是PlotItem这个绘图核心对象。你只需要从PlotWidget里取出内部的PlotItem,剩下的代码就和示例几乎完全兼容了。
修改后的完整代码(适配PlotWidget)
import numpy as np import pyqtgraph as pg from PyQt5 import QtWidgets, QtCore # 配置pyqtgraph样式 pg.setConfigOption('background', '#ffffff') pg.setConfigOption('foreground', 'k') pg.setConfigOptions(antialias=True) app = QtWidgets.QApplication([]) # 改用QMainWindow+PlotWidget的结构(对应Qt Designer生成的UI场景) main_win = QtWidgets.QMainWindow() central_widget = QtWidgets.QWidget() layout = QtWidgets.QVBoxLayout(central_widget) main_win.setCentralWidget(central_widget) # 添加坐标标签 label = pg.LabelItem(justify='right') layout.addWidget(label) # 这里就是你从Qt Designer提升而来的PlotWidget对象 p1 = pg.PlotWidget() layout.addWidget(p1) main_win.setWindowTitle('pyqtgraph crosshair with PlotWidget') p1.setAutoVisible(y=True) # 生成绘图数据 data1 = 10000 + 15000 * pg.gaussianFilter(np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000) p1.plot(data1, pen="r") # -------------------------- 关键适配部分 -------------------------- # 从PlotWidget中获取内部的PlotItem(这是和示例代码的核心区别) plot_item = p1.getPlotItem() # 创建十字线并添加到PlotItem上 vLine = pg.InfiniteLine(angle=90, movable=False) hLine = pg.InfiniteLine(angle=0, movable=False) plot_item.addItem(vLine, ignoreBounds=True) plot_item.addItem(hLine, ignoreBounds=True) # 获取PlotItem的视图盒子,和示例逻辑对齐 vb = plot_item.vb # ------------------------------------------------------------------ def mouseMoved(evt): pos = evt[0] # 判断鼠标是否在PlotItem的绘图区域内 if plot_item.sceneBoundingRect().contains(pos): mousePoint = vb.mapSceneToView(pos) index = int(mousePoint.x()) if index > 0 and index < len(data1): label.setText("<span style='font-size: 12pt'>x=%0.1f, <span style='color: green'>y2=%0.1f</span>" % (mousePoint.x(), data1[index])) vLine.setPos(mousePoint.x()) hLine.setPos(mousePoint.y()) # 绑定鼠标移动信号(用PlotItem的scene信号,和示例逻辑一致) proxy = pg.SignalProxy(plot_item.scene().sigMouseMoved, rateLimit=60, slot=mouseMoved) main_win.show() if __name__ == '__main__': import sys if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): app.exec_()
核心改动说明
- 获取内部PlotItem:调用
p1.getPlotItem()拿到PlotWidget包裹的绘图核心对象,这是解决类型不匹配的关键。 - 对齐视图盒子(vb):示例中的
p1.vb是PlotItem的视图盒子,现在需要改成从获取到的plot_item中取vb。 - 信号与元素添加:十字线的添加、鼠标信号的绑定都切换到
plot_item上操作,完全对齐示例的逻辑,避免容器控件带来的层级问题。
如果是在Qt Designer生成的UI代码中使用,只需要把上面的p1替换成你UI文件中的self.xxxPlotWidget(比如self.plotWidget),其余逻辑完全复用即可。
内容的提问来源于stack exchange,提问作者Trifon Trifonov
相关产品推荐
相关产品推荐

