如何在 QLabel 中约束 QRubberBand?

How to constrain a QRubberBand within a QLabel?

我正在构建一个 Qt5 应用程序,允许用户用鼠标在图像上绘制橡皮筋,select 图像的特定区域进行进一步处理。

我的代码只允许用户开始绘制橡皮筋,通过将 QLabel 子class 到自定义 class (frame_displayer) 其中 mousePressEvent() 被覆盖,因此仅当在自定义 classed 小部件中发生鼠标按下时才会调用。

问题是,当初始点击在 frame_displayer、mouseMoveEvent() 内时,我用来相应地更改橡皮筋大小的函数不断得到即使鼠标光标已被拖出 frame_displayer.

也会调用

我尝试使用 leaveEvent()enterEvent() 来控制在 mouseMoveEvent 中编码的 class 布尔标志可以依靠知道光标是否仍在小部件内。但是,leaveEvent()enterEvent() 仅在未按住鼠标按钮时才被调用,因此它们无法用于约束橡皮筋.

此外,underMouse() 总是 return 正确,原因我不知道。

frame_displayer.cpp

的片段
frame_displayer::frame_displayer(QWidget * parent) : QLabel(parent)
{
    _rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
}

void frame_displayer::mousePressEvent(QMouseEvent *event)
{
    _lastClickedBtn = event->button();
    if (_lastClickedBtn == Qt::LeftButton)
    {
        _mouseOriginClickPoint = event->pos();
        _rubberBand->setGeometry(QRect(_mouseOriginClickPoint, _mouseClickPoint));
        _rubberBand->show();
    }
}

void frame_displayer::mouseMoveEvent(QMouseEvent *event)
{
    if(_rubberBand != nullptr)
    {
        if (this->underMouse())
        {
            if (_lastClickedBtn == Qt::LeftButton)
            {
                QPoint mouseCurrentPoint = event->pos();
                _rubberBand->setGeometry(QRect(_mouseOriginClickPoint, mouseCurrentPoint).normalized());
            }
        }
    }
}

void frame_displayer::mouseReleaseEvent(QMouseEvent *event)
{
    _mouseOriginClickPoint = QPoint();
    _lastClickedBtn = Qt::MidButton;
    if(_rubberBand != nullptr)
    {
        _rubberBand->hide();
        _rubberBand->clearMask();
    }
}

void frame_displayer::leaveEvent(QEvent *event)
{
    qDebug() << "Leaving";
}

void frame_displayer::enterEvent(QEvent *event)
{
    qDebug() << "Entering";
}

提前致谢!

我认为这是预期的行为。如果你想限制橡皮筋的范围,那么只需将它们夹在 mouseMoveEvent override...

void frame_displayer::mouseMoveEvent(QMouseEvent *event)
{
    if(_rubberBand != nullptr)
    {
        if (this->underMouse())
        {
            if (_lastClickedBtn == Qt::LeftButton)
            {
                QPoint mouseCurrentPoint = event->pos();

                /*
                 * Clamp mouseCurrentPoint to the QRect of this widget.
                 */
                auto clamp_rect = rect();
                mouseCurrentPoint.rx() = std::min(clamp_rect.right(), std::max(clamp_rect.left(), mouseCurrentPoint.x()));
                mouseCurrentPoint.ry() = std::min(clamp_rect.bottom(), std::max(clamp_rect.top(), mouseCurrentPoint.y()));
                _rubberBand->setGeometry(QRect(_mouseOriginClickPoint, mouseCurrentPoint).normalized());
            }
        }
    }
}