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

QRubberBand非左上至右下拖拽时绘制不连续问题求助

问题核心原因

你的业务代码出现该问题的核心错误是坐标体系不匹配:
QRubberBand的父控件为当前Graph对象,调用setGeometry()方法时传入的坐标必须是相对于父控件(Graph)的局部坐标,但你的代码中存储的起点、移动时取的鼠标位置都用了全局屏幕坐标globalPos(),坐标体系错位就会导致除左上到右下方向外,其余方向绘制时矩形位置计算错误,出现跳变。


修正方案

将选框绘制相关的坐标全部替换为当前Graph控件的局部坐标即可,修正后代码如下:

void Graph::onMousePress(QMouseEvent* event){
    if ((event->buttons() & Qt::RightButton) == Qt::RightButton) {
        m_RMBPressed = true;
        // 存储相对当前控件的局部坐标,不使用全局坐标
        m_origin = event->pos();
        if (!m_rubberBand) {
            m_rubberBand = new QRubberBand(QRubberBand::Rectangle, qobject_cast<QWidget*>(this));
        }
        m_rubberBand->setGeometry(QRect(m_origin, QSize()));
        m_rubberBand->show();
    }
}

void Graph::onMouseRelease(QMouseEvent* event){
    m_RMBPressed = false;
    if (m_rubberBand) {
        m_rubberBand->hide();
    }
}

void Graph::onMouseMove(QMouseEvent* event){
    if (m_RMBPressed) {
        // 用局部坐标计算矩形,setGeometry本身会触发重绘,不需要额外调用update
        auto rectangle = QRect(m_origin, event->pos()).normalized();
        m_rubberBand->setGeometry(rectangle);
    }
}

如果业务逻辑中需要用全局坐标做选框命中判断,可通过mapToGlobal()方法将最终的局部坐标选框转换为全局坐标,不要在给QRubberBand设置位置时直接传入全局坐标。


额外排查点

如果修改后仍存在问题,可检查两个场景:

  • 确认没有其他事件过滤器拦截了Graph控件的鼠标移动事件,导致部分移动事件没有触发回调
  • 确认Graph控件的父级没有滚动偏移,如果存在滚动偏移,需要把滚动偏移量计入局部坐标计算

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:54:04