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

如何检测与选择矩形相交的所有Qt图表序列

关于Qt Chart矩形选区检测序列的问题解答

嘿,刚好我之前在做Qt图表交互的时候踩过类似的坑,来给你拆解下这些问题:

1. 能不能用QGraphicsItem::collidesWith()检测QLineSeries?

很遗憾,这条路走不通。Qt Charts的内部实现里,QLineSeries和QScatterSeries对应的图形元素是被封装在私有类里的,外部代码根本拿不到它们的QGraphicsItem实例——你没法直接调用shape()或者collidesWith()来做碰撞检测,官方也没提供暴露这些item的接口,所以这个方案直接放弃吧。

2. 改用QPainterPath是更合适的方案,具体这么做:

这确实是Qt官方推荐的几何检测方式,完全不用手动计算插值点,正好匹配你的需求。步骤如下:

第一步:把鼠标拖拽的矩形转换成图表坐标系的QPainterPath

鼠标拖拽的矩形默认是在场景坐标系(Scene Coordinate)或者视图坐标系(Viewport Coordinate)里的,你需要先把它转换成QChart的绘图区域坐标系(Plot Area Coordinate)(也就是数据点所在的坐标系):

// 假设你已经拿到了拖拽的矩形sceneRect(QRectF类型,scene坐标)
QRectF plotRect = chart()->mapToPlotArea(sceneRect);
QPainterPath selectionPath;
selectionPath.addRect(plotRect);

第二步:遍历所有序列,检测与选区路径的相交/包含关系

  • 对于QLineSeries:
    你可以把整个序列的线段构建成一个QPainterPath,直接判断这个路径和选区路径是否相交:

    QLineSeries *series = ...; // 你的线序列
    QPainterPath seriesPath;
    bool firstPoint = true;
    for (const QPointF &point : series->points()) {
        if (firstPoint) {
            seriesPath.moveTo(point);
            firstPoint = false;
        } else {
            seriesPath.lineTo(point);
        }
    }
    // 判断线段是否和选区相交(哪怕端点不在选区内,中间穿过也会触发)
    if (selectionPath.intersects(seriesPath)) {
        // 这个序列和选区相交,标记它
    }
    

    QPainterPath::intersects()会自动处理线段和矩形的几何相交,完美解决你说的“插值线段”检测需求,不用手动计算中间点。

  • 对于QScatterSeries:
    判断每个数据点是否在选区内,或者和选区边界相交(给点加个小矩形是适配散点的实际显示大小,避免漏检):

    QScatterSeries *scatterSeries = ...;
    for (const QPointF &point : scatterSeries->points()) {
        // 散点实际有大小,用小矩形代替点做检测
        QRectF pointRect(point.x()-2, point.y()-2, 4, 4);
        if (selectionPath.contains(point) || selectionPath.intersects(pointRect)) {
            // 点在选区内或和选区相交,标记序列
            break; // 只要有一个点符合,整个序列就算选中
        }
    }
    

小优化:

如果你的序列数据量很大,可以改成逐个检测相邻线段和选区的相交,一旦发现相交就停止遍历该序列,能节省不少性能。

3. hovered()信号在左键按下时不触发的原因

这是Qt事件分发机制的特性:当你按下鼠标左键时,当前被点击的QGraphicsItem会捕获鼠标焦点,进入“拖动”状态,此时Qt会暂停发送hover事件——系统认为你现在是在拖拽操作,而非hover浏览。所以用hovered信号来检测选区序列的方案根本不可行,放弃就好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:09:43