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

Qt6.5:MouseMove事件阻止Hovered信号触发的问题求助

Qt/C++ 事件冲突问题:重写QChartView的mouseMove后hovered信号失效

我是Qt和C++新手,开发了一个继承QChartView的组件,想要重写QChartView的mouseMove事件,同时将QScatterSeries的hovered信号连接到类内的槽函数。但重写mouseMove事件后,hovered信号对应的槽函数不再执行(tooltip无法显示),移除mouseMove事件则功能正常,求解决该事件冲突的方案。


可复现代码

interactive_chart.h

#ifndef INTERACTIVECHARTVIEW_H
#define INTERACTIVECHARTVIEW_H

#include <QtCharts/QChartView>
#include <QDebug>
#include <QToolTip>
#include <QCursor>
#include <QtCharts/QScatterSeries>
#include <QtCharts/QValueAxis>
#include <QPainter>
#include <QTimer>
#include  <QCursor>

namespace Common::ScatterChartGroup
{
    class InteractiveChartView : public QChartView
    {
    private:
        const int panningStep = 10;
        // 用于存储用户平移输入,供重置使用
        QChart *chart;
        QValueAxis *axisX;
        QValueAxis *axisY;
        QTimer timer;
        QScatterSeries *series;
        void onMouseMoveStop();
        void drawChart(QValueAxis *x_axis, QValueAxis *y_axis);
        void mouseMoveEvent(QMouseEvent *event);
        InteractiveChartView(QChart *chart);
    public:
        static InteractiveChartView* getInstance();
    public slots:
        void onMouseHovered(const QPointF &point, bool state);
    };
}

#endif // INTERACTIVECHARTVIEW_H

interactiveChart.cpp

#include "interactive_chart_view.h"

InteractiveChartView::InteractiveChartView(QChart *chart): QChartView (chart)
{
    this->chart = chart;
    chart->setAcceptHoverEvents(true);
    chart->legend()->hide();
    axisX = new QValueAxis;
    axisY = new QValueAxis;
    chart->addAxis(axisX, Qt::AlignBottom);
    chart->addAxis(axisY, Qt::AlignLeft);
    drawChart(axisX,axisY);
    // 检测鼠标停止移动
    setMouseTracking(true);
    timer.setInterval(250);
    timer.setSingleShot(true);

    this->connect(this->series, &QScatterSeries::hovered, this,
                  &InteractiveChartView::onMouseHovered);
    this->connect(&timer,&QTimer::timeout,this, &InteractiveChartView::onMouseMoveStop);
}

InteractiveChartView* InteractiveChartView::getInstance()
{
    QChart *chart = new QChart();
    InteractiveChartView  *interactiveChartView = new InteractiveChartView(chart);
    return interactiveChartView;
}

void InteractiveChartView::onMouseHovered(const QPointF &point, bool state)
{
    QString tooltipText = "x: " + QString::number(point.x()) + "\ny: " + QString::number(point.y());
    if(state)
    {
        QToolTip::showText(QCursor::pos(),tooltipText ,nullptr);
    }else
    {
        QToolTip::hideText();
    }
}

void InteractiveChartView::onMouseMoveStop()
{
    qDebug() << "Mouse Stopped";
}

void InteractiveChartView::drawEmptyChart(QValueAxis *xAxis, QValueAxis *yAxis)
{
    series->attachAxis(xAxis);
    series->attachAxis(yAxis);
    axisX->setRange(0,10);
    axisY->setRange(0,10);
    QRandomGenerator randGenerator; // 测试用临时随机数据生成器
    for (int i = 0;i<=10;i++) {
        series.append(QPointF(randGenerator.bounded(20.0),randGenerator.bounded(20.0)));
    }
}

void InteractiveChartView::mouseMoveEvent(QMouseEvent *event)
{
    timer.start();

}

解决方案

问题核心是重写mouseMoveEvent时没有调用父类的实现,导致QChartView内部处理hover状态的逻辑被阻断——QChartView需要通过mouseMove事件追踪鼠标位置,判断是否落在散点上,进而触发hovered信号。

1. 修复mouseMoveEvent函数

修改你的mouseMoveEvent,添加父类方法调用:

void InteractiveChartView::mouseMoveEvent(QMouseEvent *event)
{
    timer.start();
    // 调用父类的mouseMoveEvent,保证原有hover检测逻辑正常执行
    QChartView::mouseMoveEvent(event);
}

2. 修复代码中的其他问题

  • 函数声明与实现不匹配:头文件中声明的是drawChart,但cpp中实现的是drawEmptyChart,需要统一函数名。
  • series指针未初始化:在构造函数中添加实例创建和添加到chart的代码:
// 在构造函数中添加
series = new QScatterSeries();
chart->addSeries(series);

完成以上修改后,hovered信号会正常触发,tooltip可以显示,同时鼠标停止移动的检测逻辑也能正常工作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 02:12:32