使用qt制作的无边框窗口,只需在其flag中加入FramelessWindowHint。
然而,无边框窗口意味着,无法使用原有的边框拉伸,拖拽功能。
在qwidget中,有很多实现的方法,比如重写
+ mouseMoveEvent(QMouseEvent *event)+ mousePressEvent(QMouseEvent *event)
+ mouseReleaseEvent(QMouseEvent *event)
这几个事件即可很容易的完成无边框窗口的拉伸,拖拽功能。ps :重写nativeEvent(const QByteArray &eventType, void *message, long *result)可以获得最好的效果~
但是在qml,由于qwindow和qwidget的实现方式完全不同,而qquickwindow继承自qwindow,使用上述的方法当然也可以如widget一样的工作,然鹅经过测试闪烁严重,体验极差,于是就有了另一种方法。
直接使用MouseArea进行拉伸,拖拽。
qml代码如下:
import QtQuick 2.7 /* ↑ ↑ ↑ ←|1| |2| |3|→ ←|4| |5| |6|→ ←|7| |8| |9|→ ↓ ↓ ↓ 分8个缩放区域 |5|为拖动区域 target 缩放目标 startPoint 鼠标起始点 fixedPont 用于固定窗口的点 每一个area 大小 8 x 8 */ Item { id: area property var target: undefined; property point startPoint: Qt.point(0, 0); property point fixedPont: Qt.point(0, 0); MouseArea { id: area1 x: 0 y: 0 width: 8 height: 8 hoverEnabled: true onEntered: cursorShape = Qt.SizeFDiagCursor; onExited: cursorShape = Qt.ArrowCursor; onPressed: startPoint = Qt.point(mouseX, mouseY); onPositionChanged: { if(pressed) { var offsetX = mouse.x - startPoint.x; var offsetY = mouse.y - startPoint.y; if ((target.width - offsetX) >= target.minimumWidth) //如果本次调整小于最小限制,则调整为最小 { target.width -= offsetX; target.x += offsetX; } else { target.x += (target.width - target.minimumWidth); target.width -= (target.width - target.minimumWidth); } if ((target.height - offsetY) >= target.minimumHeight && offsetY != 0) { target.height -= offsetY; target.y += offsetY; } } } } MouseArea { id: area2 x: 8 y: 0 width: target.width - 16 height: 8 hoverEnabled: true onEntered: cursorShape = Qt.SizeVerCursor; onExited: cursorShape = Qt.ArrowCursor; onPressed: startPoint = Qt.point(mouseX, mouseY); onPositionChanged: { if(pressed) { var offsetY = mouse.y - startPoint.y; if ((target.height - offsetY) >= target.minimumHeight && offsetY != 0) { target.height -= offsetY; target.y += offsetY; } } } } MouseArea { id: area3 x: target.width - 8 y: 0 width: 8 height: 8 hoverEnabled: true onEntered: cursorShape = Qt.SizeBDiagCursor; onExited: cursorShape = Qt.ArrowCursor onPressed: { startPoint = Qt.point(mouseX, mouseY); fixedPont = Qt.point(target.x, target.y) } onPositionChanged: { if(pressed) { var offsetX = mouse.x - startPoint.x; var offsetY = mouse.y - startPoint.y; print (offsetX, offsetY) if ((target.width + offsetX) >= target.minimumWidth && offsetX != 0) { target.width += offsetX; target.x = fixedPont.x; } if ((target.height - offsetY) >= target.minimumHeight && offsetY != 0) { target.height -= offsetY; target.y += offsetY; } } } } MouseArea { id: area4 x: 0 y: 8 width: 8 height: target.height - 16 hoverEnabled: true onEntered: cursorShape = Qt.SizeHorCursor; onExited: cursorShape = Qt.ArrowCursor; onPressed: { startPoint = Qt.point(mouseX, mouseY); } onPositionChanged: { if(pressed) { var offsetX = mouse.x - startPoint.x; if ((target.width - offsetX) >= target.minimumWidth) { target.width -= offsetX; target.x += offsetX; } } } } MoveMouseArea { id: area5 x: 8 y: 8 width: area.target.width - 16 height: area.target.height - 16 target: area.target } MouseArea { id: area6 x: target.width - 8 y: 8 width: 8 height: target.height - 16 hoverEnabled: true property real fixedX: 0; onEntered: cursorShape = Qt.SizeHorCursor; onExited: cursorShape = Qt.ArrowCursor; onPressed: { startPoint = Qt.point(mouseX, mouseY); fixedPont = Qt.point(target.x, target.y) } onPositionChanged: { if(pressed) { var offsetX = mouse.x - startPoint.x; if ((target.width + offsetX) >= target.minimumWidth && offsetX != 0) { target.width += offsetX; target.x = fixedPont.x; } } } } MouseArea { id: area7 x: 0 y: target.height - 8 width: 8 height: target.height - 16 hoverEnabled: true property real fixedX: 0; onEntered: cursorShape = Qt.SizeBDiagCursor; onExited: cursorShape = Qt.ArrowCursor; onPressed: { startPoint = Qt.point(mouseX, mouseY); fixedPont = Qt.point(target.x, target.y) } onPositionChanged: { if (pressed) { var offsetX = mouse.x - startPoint.x; var offsetY = mouse.y - startPoint.y; if ((target.width - offsetX) >= target.minimumWidth && offsetX != 0) { target.width -= offsetX; target.x += offsetX; } if ((target.height + offsetY) >= target.minimumHeight && offsetY != 0) { target.height += offsetY; target.y = fixedPont.y; } } } } MouseArea { id: area8 x: 8 y: target.height - 8 width: target.height - 16 height: 8 hoverEnabled: true property real fixedX: 0; onEntered: cursorShape = Qt.SizeVerCursor; onExited: cursorShape = Qt.ArrowCursor; onPressed: { startPoint = Qt.point(mouseX, mouseY); fixedPont = Qt.point(target.x, target.y) } onPositionChanged: { if (pressed) { var offsetY = mouse.y - startPoint.y; if ((target.height + offsetY) >= target.minimumHeight && offsetY != 0) { target.height += offsetY; target.y = fixedPont.y; } } } } MouseArea { id: area9 x: target.width - 8 y: target.height - 8 width: 8 height: 8 hoverEnabled: true onEntered: cursorShape = Qt.SizeFDiagCursor; onExited: cursorShape = Qt.ArrowCursor onPressed: { startPoint = Qt.point(mouseX, mouseY); fixedPont = Qt.point(target.x, target.y) } onPositionChanged: { if(pressed) { var offsetX = mouse.x - startPoint.x; var offsetY = mouse.y - startPoint.y; if ((target.width + offsetX) >= target.minimumWidth && offsetX != 0) { target.width += offsetX; target.x = fixedPont.x; } if ((target.height + offsetY) >= target.minimumHeight && offsetY != 0) { target.height += offsetY; target.y = fixedPont.y; } } } } }
还有很多判断minimum,maximum什么的没有写全,但很简单,就不多展示了。
其中的MoveMouseArea为:
import QtQuick 2.7 MouseArea { hoverEnabled: true property var target: undefined; property point startPoint: Qt.point(0, 0); property point offsetPoint: Qt.point(0, 0); onPressed: { cursorShape = Qt.SizeAllCursor; startPoint = Qt.point(mouseX, mouseY); } onPositionChanged: { if(pressed) { offsetPoint = Qt.point(mouse.x - startPoint.x, mouse.y - startPoint.y); target.x = target.x + offsetPoint.x; target.y = target.y + offsetPoint.y; } } onReleased: { cursorShape = Qt.ArrowCursor; } }
因为在其他地方并不需要拉伸操作,所以将区域|5|单独作为一个qml文件使用。
还有一点关于qml,闪烁严重的一部分原因是使用了anchors定位引起的,所以在窗口中的最底层的item使用坐标方式进行定位。其他item则不用。
可以测试一下,还算可以,基本可以使用了,但仍然达不到widget那么流畅完美的程度。