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
相关产品推荐
相关产品推荐

