You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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_()

核心改动说明

  1. 获取内部PlotItem:调用p1.getPlotItem()拿到PlotWidget包裹的绘图核心对象,这是解决类型不匹配的关键。
  2. 对齐视图盒子(vb):示例中的p1.vb是PlotItem的视图盒子,现在需要改成从获取到的plot_item中取vb。
  3. 信号与元素添加:十字线的添加、鼠标信号的绑定都切换到plot_item上操作,完全对齐示例的逻辑,避免容器控件带来的层级问题。

如果是在Qt Designer生成的UI代码中使用,只需要把上面的p1替换成你UI文件中的self.xxxPlotWidget(比如self.plotWidget),其余逻辑完全复用即可。

内容的提问来源于stack exchange,提问作者Trifon Trifonov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:35:25