简体   繁体   English

重新实现调整大小事件

[英]Reimplement resize event

My widget is frameless because of the sleek looks and so I need to reimplement the resize behaviour. 由于外观时尚,我的小部件是无框架的,因此我需要重新实现调整大小的行为。

If I drag the bottom right corner it already works with this code: 如果我拖动右下角的代码,则该代码已经可以使用:

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

But what about all the other corners? 但是其他所有角落呢? For example the bottom left corner. 例如,左下角。 As one expects, it should behave as if the top right corner of the widget would be fixed. 正如人们所期望的那样,它的行为就好像小部件的右上角将被固定。 But in the resize function, the upper left corner is fixed, because there is the event.pos()==0 . 但是在resize函数中,左上角是固定的,因为存在event.pos()==0 My idea was to resize the window and then move it, so that it looks as if it would not move, but only change size around the upper left corner. 我的想法是调整窗口的大小然后移动它,以便看起来好像它不会移动,而只是更改左上角的大小。 As this leads to flickering and even not the perfect result, is there a better way? 由于这会导致闪烁甚至无法达到完美的效果,是否有更好的方法?

EDIT: Solution: 编辑:解决方案:

a) You can define in mousePressEvent : a)您可以在mousePressEvent定义:

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

and in mouseMoveEvent 并在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);

or 要么

b) in mouseMoveEvent b)在mouseMoveEvent

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

To both resize and move the window in one step without flickering, you should use QWidget::setGeometry(QRect) by providing a modified rectangle previously fetched using the corresponding getter function QWidget::geometry() . 要一步调整窗口大小移动而不闪烁,应使用QWidget::setGeometry(QRect)是提供一个事先使用相应的吸气剂函数QWidget::geometry()提取的修改后的矩形。

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

To modify a corner of a QRect , you could either modify each edge or the corners directly. 要修改QRect的角,可以直接修改每个边或角。 Depending on the rest of your logic, one makes more sense than the other. 根据您逻辑的其余部分,一个比另一个更有意义。 I'd prefer the second of the following two options: 我希望使用以下两个选项中的第二个:

Example using corners: 使用角的示例:

If you detect that the user drags the bottom left corner, use 如果您检测到用户拖动了左下角,请使用

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

However, you of course need to consider edges too, and if you consider corners as separate cases this results in eight cases to be considered in the mouse event. 但是,您当然也需要考虑边缘,如果将角视为单独的情况,则在鼠标事件中会考虑八种情况。

Example using only edges: 仅使用边的示例:

If you detect that the mouse is on the left edge (it might be as well on the top or bottom corner, which are only special cases, so for now we ignore that): 如果您检测到鼠标在左边缘(它可能在上角或下角,这只是特殊情况,所以现在我们忽略它):

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

and if you detect it is on the bottom edge, then 如果您发现它在底部边缘,则

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

so if both cases are true, this effectively moves the corner of the rect. 因此,如果两种情况都成立,这将有效地移动矩形的角。 So you only need to consider four cases to drag all edges and corners of your window! 因此,您只需要考虑四种情况即可拖动窗口的所有边缘和角落! This assumes that you have a single widget which handles the resize (ie your top level widget, which has a margin on the layout to have the children not touch the window edge), and do not add a widget for each corner / edge. 假设您有一个处理调整大小的小部件(即您的顶级小部件,在布局上有一个空白,以使子级不触摸窗口边缘),并且为每个角/边添加小部件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM