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

QCustomPlot图表切换时Tracer与Label无法隐藏的问题求助

问题:跨图表切换时Tracer和Label无法隐藏

鼠标从一个图表移至另一个图表后,原图表的tracer和label无法消失。需求为:鼠标悬停图表时显示带label的tracer,切换到其他图表时,原图表的tracer和label需消失,但目前切换后tracer仍存在。相关代码如下:

void Plotter::onMouseMoveEvent(QMouseEvent* event)
{
    QPoint mousePos = event->pos();
    double coordX = xAxis->pixelToCoord(event->pos().x());
    double coordY = yAxis->pixelToCoord(event->pos().y());

    if (rect().contains(mousePos))
    {
        customizeTracer(coordX, coordY);
        QPointF tracerCoords = mTracer->position->coords();
        double xTracerCoord = tracerCoords.x();
        double yTracerCoord = tracerCoords.y();

        QTime time = QTime(0, 0).addMSecs(static_cast<int>(xTracerCoord));
        QString formattedTime = time.toString("HH:mm:ss.zzz");
        customizeLabel(xTracerCoord, yTracerCoord, formattedTime);
        replot();
    }
    else
    {
        removeItem(mTracer);
        removeItem(mLabel);
        replot();
    }
}

void Plotter::customizeTracer(const double coordX, const double coordY)
{
    mTracer->setGraph(graph());
    mTracer->setStyle(QCPItemTracer::tsCircle);
    mTracer->position->setType(QCPItemPosition::ptPlotCoords);
    mTracer->position->setCoords(coordX, coordY);
    mTracer->setGraphKey(coordX);
    mTracer->setPen(QPen(QColor("red")));
    mTracer->setSize(5);
    mTracer->setBrush(QColor("red"));
    mTracer->setInterpolating(true);
    mTracer->setVisible(true);
    mTracer->updatePosition();
}

void Plotter::customizeLabel(const double coordX, const double coordY, const QString& formattedTime)
{
    mLabel->setPositionAlignment(Qt::AlignLeading | Qt::AlignBottom);
    mLabel->position->setCoords(coordX, coordY);
    mLabel->setText(QString("Time %1 | Position %2").arg(formattedTime).arg(coordY));
}

问题原因

原代码中else分支使用removeItem移除tracer和label,后续customizeTracer直接操作mTracer时,若未重新将其添加回图表,会导致对象状态异常;同时customizeLabel未显式设置label可见性,且频繁移除/添加项效率低下,最终导致切换图表后tracer无法正常隐藏。

解决方案

核心思路:通过控制可见性替代移除/添加操作,确保mTracer和mLabel始终处于图表中,仅切换显示状态。

1. 修改onMouseMoveEvent的else分支

else
{
    mTracer->setVisible(false);
    mLabel->setVisible(false);
    replot();
}

2. 完善customizeLabel函数

添加显式设置label可见性的代码,确保鼠标悬停时label正常显示:

void Plotter::customizeLabel(const double coordX, const double coordY, const QString& formattedTime)
{
    mLabel->setPositionAlignment(Qt::AlignLeading | Qt::AlignBottom);
    mLabel->position->setCoords(coordX, coordY);
    mLabel->setText(QString("Time %1 | Position %2").arg(formattedTime).arg(coordY));
    mLabel->setVisible(true); // 确保鼠标在图表上时label显示
}

3. 初始化时添加项到图表

确保在Plotter的构造函数中,已将mTracer和mLabel添加到图表中(否则setVisible无效):

// 构造函数示例
Plotter::Plotter(QWidget *parent) : QCustomPlot(parent)
{
    mTracer = new QCPItemTracer(this);
    mLabel = new QCPItemText(this);
    addItem(mTracer);
    addItem(mLabel);
    // 初始状态隐藏
    mTracer->setVisible(false);
    mLabel->setVisible(false);
}

说明

通过控制可见性替代移除操作,既避免了对象状态异常,又提升了性能,完全满足鼠标跨图表切换时隐藏tracer和label的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 02:58:22