如何在QLabel中限制QRubberBand?

时间:2019-01-16 14:49:03

标签: c++ qt5 qmouseevent rubber-band

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

通过将QLabel子类化为自定义类(frame_displayer),我的代码只允许用户开始绘制橡皮筋,该自定义类将覆盖 mousePressEvent(),因此仅在鼠标单击时调用按下会在自定义分类的小部件内发生。

问题在于,当初次单击位于frame_displayer内部时,我用来更改橡皮筋大小的函数 mouseMoveEvent()仍然被调用,即使拖动鼠标光标也是如此在frame_displayer之外。

我尝试使用 leaveEvent() enterEvent()来控制类布尔标志,mouseMoveEvent内部的代码可以依靠该标志来了解光标是否仍在小部件。但是, leaveEvent() enterEvent()都仅在不按住鼠标按钮的情况下才被调用,因此使它们无助于约束橡皮筋。

此外,出于我未知的原因, underMouse()始终返回true。

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";
}

谢谢!

1 个答案:

答案 0 :(得分:0)

我认为这是预期的行为。如果您想限制橡皮筋的范围,则只需将其夹在mouseMoveEvent替代中...

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());
            }
        }
    }
}