使用鼠标移动qwidget而不超过父级大小

时间:2016-02-23 03:14:44

标签: c++ qt

我在家长QWidget 中添加了 QWidget ,如下图所示:

enter image description here

儿童QWidget 内部,我使用鼠标将其移动到父级QWidget 内。

void ExportComponent::mousePressEvent(QMouseEvent *event)
{
    offset = event->pos();
}
void ExportComponent::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton)
    {
        this->move(mapToParent(event->pos() - offset));
    }
}

它表现不错,但问题是它还可以移出父QWidget大小。像这样:

enter image description here

如何让 Child QWidge t只能在ParentQWidget中移动?

2 个答案:

答案 0 :(得分:2)

您可以在if中添加一个额外的mouseMoveEvent子句,以检查子窗口小部件是否仍然在父母的内部'边界。以下示例执行此操作:

void ExportComponent::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton)
    {

        QPoint newpos_min = mapToParent(event->pos()-offset);
        QPoint newpos_max = QPoint(newpos_min.x() + this->width(), newpos_min.y() + this->height());

        if(newpos_min.x() > 0 &&
           newpos_min.y() > 0 &&
           newpos_max.x() < this->parentWidget()->width() &&
           newpos_max.y() < this->parentWidget()->height()){

            this->move(mapToParent(event->pos() - offset));
        }
    }
}

但是,您现在遇到的问题是,如果新的xy位置超出范围,则无法再进行移动。有几种方法可以解决这个问题。

  1. 一种方法是动态更新mouseMoveEvent中的偏移量。一个非常简单的版本是在移动不起作用时更新偏移量:

    ...
        this->move(mapToParent(event->pos() - offset));
    }else{
        offset = event->pos();
    }
    ...
    

    仍然不太好,因为如果鼠标移回允许的区域,这会在光标和小部件之间产生很大的间隙。

  2. 另一种可能性是分离x和y运动并单独检查dem:

    if(newpos_min.y() > 0 &&
       newpos_max.y() < this->parentWidget()->height()){
    
        this->move(this->x(), mapToParent(event->pos() - offset).y());
    }
    
    if(newpos_min.x() > 0 &&
       newpos_max.x() < this->parentWidget()->width()){
    
        this->move(mapToParent(event->pos() - offset).x(), this->y());
    }
    

    在我看来这是一个更好的版本。

  3. 但是,更新偏移量可能会增加一些改进。你只需要确保在再次移动之前,curso会回到小部件上。

答案 1 :(得分:1)

我将@ Bowdzone的代码与我的代码结合起来,以提供更好的解决方案。这种新算法工作得更顺畅,仍能满足我的目的。

void ExportComponent::mouseMoveEvent(QMouseEvent *event)
{
    //Using left mouse to move the control
    if (event->buttons() & Qt::LeftButton)
    {
        //Excute movement follow mouse position
        move(mapToParent(event->pos() - m_offset));
        //Make sure control do not move out parent size
        if (x() < 0)
            move(1, y());
        if (y() < 0)
            move(x(), 1);
        if (x() + width() > parentWidget()->width())
            move(parentWidget()->width() - 1 - width(), y());
        if (y() + height() > parentWidget()->height())
            move(x(), parentWidget()->height() - 1 - height());
    }
}