重新实现大小调整事件

Reimplement resize event

本文关键字:调整 事件 实现 新实现      更新时间:2023-10-16

我的小部件是无框架的,因为它看起来很时尚,所以我需要重新实现调整大小的行为。

如果我拖动右下角,它已经可以使用以下代码:

void mouseMoveEvent(QMouseEvent *event) {
resize(event->pos().x(), event->pos().y());
}

但其他角落呢?例如左下角。正如人们所期望的那样,它的行为应该像小部件的右上角将被修复一样。但在调整大小函数中,左上角是固定的,因为有event.pos()==0。我的想法是调整窗口的大小,然后移动它,这样它看起来就不会移动,只会改变左上角的大小。由于这会导致闪烁,甚至不是完美的结果,有更好的方法吗?

编辑:解决方案:

a) 您可以在mousePressEvent:中定义

offset = event->pos();
initialFixedCornerPosX = this->width()+this->pos().x();
initialFixedCornerPosY = this->pos().y();

和在mouseMoveEvent

int x = event->globalX();
int y = event->globalY();
int x_w = offset.x();
int y_w = offset.y();
setGeometry(x-x_w,initialFixedCornerPosY,initialFixedCornerPosX-x+x_w,y-initialFixedCornerPosY);

b) 在mouseMoveEvent

QRect rect = geometry();
rect.setBottomLeft(event->globalPos());
setGeometry(rect);

要在不闪烁的情况下一步调整的大小和移动窗口,您应该使用QWidget::setGeometry(QRect),提供一个先前使用相应的getter函数QWidget::geometry()获取的修改矩形。

QRect rect = geometry();
// (then modify...)
setGeometry(rect);

要修改QRect的角点,可以直接修改每条边或角点。根据你的其他逻辑,其中一个比另一个更有意义。我更喜欢下面两个选项中的第二个:

使用拐角的示例:

如果检测到用户拖动左下角,请使用

rect.setBottomLeft(event->pos());

然而,当然也需要考虑边,如果将角视为单独的情况,则会导致在鼠标事件中考虑八种情况。

仅使用边缘的示例:

如果你检测到鼠标在左边缘(它可能也在上角或下角,这只是特殊情况,所以现在我们忽略它):

rect.setLeft(event->pos().x());

如果你检测到它在底部边缘,那么

rect.setBottom(event->pos().y());

因此,如果这两种情况都是真的,这就有效地移动了rect的角。所以你只需要考虑四种情况就可以拖动窗口的所有边和角!这假设您有一个单独的小部件来处理大小调整(即您的顶级小部件,它在布局上有一个边距,以使子窗口不接触窗口边缘),并且不要为每个角落/边缘添加一个小部件。