Qt开发中如何让QRubberBand控件正常显示工具提示?
问题原因
QRubberBand 控件默认开启了 Qt::WA_TransparentForMouseEvents 属性,所有鼠标事件会直接穿透控件传递给下层的父控件,控件自身无法捕获鼠标悬停(hover)事件。工具提示的触发依赖控件接收到鼠标悬停信号,因此仅设置setToolTip、Qt::WA_AlwaysShowToolTips或调整提示时长都无法让提示弹出。
修复方案
根据你的交互需求二选一即可:
- 不需要在QRubberBand区域做拖拽选框/调整选框大小的交互:直接在初始化代码中追加一行关闭鼠标穿透即可,修改后代码如下:
roiRB = new QRubberBand(QRubberBand::Rectangle, this); roiRB->setGeometry(QRect(QPoint(1,1), QPoint(100,100))); // 关闭鼠标事件穿透,让控件可以接收鼠标事件 roiRB->setAttribute(Qt::WA_TransparentForMouseEvents, false); roiRB->setAttribute(Qt::WA_AlwaysShowToolTips); roiRB->setToolTip("Hello"); roiRB->setToolTipDuration(1000);
- 需要保留父控件原有的选框交互(如拖拽绘制、调整选框尺寸):自定义一个继承自
QRubberBand的子类,将截获的鼠标事件转发给父控件,既不影响原有交互,也能正常触发工具提示,示例代码如下:
// 自定义支持工具提示的RubberBand类 class TooltipEnabledRB : public QRubberBand { public: using QRubberBand::QRubberBand; protected: // 转发所有鼠标事件给父控件 void mousePressEvent(QMouseEvent* e) override { QRubberBand::mousePressEvent(e); if (parentWidget()) QApplication::sendEvent(parentWidget(), e); } void mouseMoveEvent(QMouseEvent* e) override { QRubberBand::mouseMoveEvent(e); if (parentWidget()) QApplication::sendEvent(parentWidget(), e); } void mouseReleaseEvent(QMouseEvent* e) override { QRubberBand::mouseReleaseEvent(e); if (parentWidget()) QApplication::sendEvent(parentWidget(), e); } };
将原代码中实例化QRubberBand的逻辑替换为实例化TooltipEnabledRB,同时保留关闭鼠标穿透、设置tooltip的相关代码即可。
注意:不需要给QRubberBand的各级父控件重复设置
Qt::WA_AlwaysShowToolTips属性,仅给QRubberBand自身设置即可。
内容的提问来源于stack exchange,提问作者madhavpcm
相关产品推荐
相关产品推荐

