Тут на форуме давеча возникла тема, которую также можно отнести к топовым, если оценивать по частоте возникновения данного вопроса. Поэтому я решил оформить ответ более развернуто, чем подразумевается в рамках форума. И пресловутый вопрос заключается в том, как на QML осуществить изменение размеров и перемещение окна приложения, которое является frameless. То есть не имеет стандартной внешней рамки и заголовка, за которые можно было бы его растягивать и перемещать.
Я сегодня приведу базовый вариант, как это сделать, так что переходим сразу к практической части. Создаем пустое Qt Quick приложение и запускаем его, ничего не меняя. А хотя нет, поместим элемент Rectangle на все окно и зададим для него какой-нибудь цвет. Базовый main.qml трансформируется в:
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
id: window
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Rectangle {
anchors.fill: parent
color: "#035570"
}
}

Соответственно, в наличии имеются все дефолтные элементы внешнего вида, в частности, панель сверху, заголовок, кнопки и т. д. По разным причинам, рассмотрение которых нас сегодня не интересует, зачастую все это требуется убрать. Для этого меняем свойство flags у Window:
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
id: window
flags: Qt.Window | Qt.FramelessWindowHint
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Rectangle {
anchors.fill: parent
color: "#035570"
}
}
Мы приблизились к сути вопроса - окно не содержит ничего лишнего, но оно стало неподвластно пользовательскому перемещению и изменению размеров.
Да, кстати, немного сопутствующей информации - если требуется сделать так, чтобы приложение не отображало значка на панели задач, вот тут:

То это можно осуществить таким образом:
flags: Qt.Widget | Qt.FramelessWindowHint
Возвращаемся к взаимодействию с окном, которое стало невозможным. Итак, базовый, наиболее наглядный и предельно надежный вариант заключается в следующем:
- добавляем дополнительные элементы по краю окна, пусть будут обычные
Rectangle - каждый из них при помощи
MouseAreaзахватывает события мыши в своих пределах - дальше - дело техники - непосредственно перемещение, либо изменение размеров окна.
Начнем с изменения размеров, добавляем максимально топорно четыре Rectangle по границам окна (ставлю разные цвета для наглядности, далее, конечно, надо будет изменить на прозрачный):
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
id: window
flags: Qt.Window | Qt.FramelessWindowHint
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Rectangle {
anchors.fill: parent
color: "#035570"
}
property var resizeRectangleSize: 5
Rectangle {
id: resizeRectangleRight
color: "red"
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
width: resizeRectangleSize
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: containsMouse ? Qt.SizeHorCursor : Qt.ArrowCursor
onPressed: {
window.startSystemResize(Qt.RightEdge);
}
}
}
Rectangle {
id: resizeRectangleLeft
color: "green"
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
width: resizeRectangleSize
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: containsMouse ? Qt.SizeHorCursor : Qt.ArrowCursor
onPressed: {
window.startSystemResize(Qt.LeftEdge);
}
}
}
Rectangle {
id: resizeRectangleTop
color: "blue"
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: resizeRectangleSize
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: containsMouse ? Qt.SizeVerCursor : Qt.ArrowCursor
onPressed: {
window.startSystemResize(Qt.TopEdge);
}
}
}
Rectangle {
id: resizeRectangleBottom
color: "yellow"
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: resizeRectangleSize
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: containsMouse ? Qt.SizeVerCursor : Qt.ArrowCursor
onPressed: {
window.startSystemResize(Qt.BottomEdge);
}
}
}
}
Полезная деятельность осуществляется при помощи window.startSystemResize(). Кроме того, задаем cursorShape для того, чтобы указатель мыши изменял свой вид при наведении на эти области:

Размер областей задаем при помощи:
property var resizeRectangleSize: 5
Отрабатывает четко, поэтому переходим ко второй подчасти - перемещению окна. Делаем абсолютно аналогично, добавляем еще один Rectangle, пусть будет оранжевый. И при нажатии на него будет происходить перемещение окна:
property var moveRectangleSize: 5
Rectangle {
color: "orange"
anchors.left: parent.left
anchors.right: parent.right
anchors.top: resizeRectangleTop.bottom
height: moveRectangleSize
MouseArea {
anchors.fill: parent
onPressed: {
window.startSystemMove();
}
}
}
Собираем, запускаем, тестируем:
Остается только изменить везде цвет: color: "transparent". Такая вот базовая идея и механизм, далее уже зависит от конкретного приложения и целей )
На всякий случай main.qml полностью, цвета на прозрачные не менял:
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
id: window
flags: Qt.Window | Qt.FramelessWindowHint
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Rectangle {
anchors.fill: parent
color: "#035570"
}
property var resizeRectangleSize: 5
property var moveRectangleSize: 5
Rectangle {
id: resizeRectangleRight
color: "red"
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
width: resizeRectangleSize
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: containsMouse ? Qt.SizeHorCursor : Qt.ArrowCursor
onPressed: {
window.startSystemResize(Qt.RightEdge);
}
}
}
Rectangle {
id: resizeRectangleLeft
color: "green"
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
width: resizeRectangleSize
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: containsMouse ? Qt.SizeHorCursor : Qt.ArrowCursor
onPressed: {
window.startSystemResize(Qt.LeftEdge);
}
}
}
Rectangle {
id: resizeRectangleTop
color: "blue"
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: resizeRectangleSize
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: containsMouse ? Qt.SizeVerCursor : Qt.ArrowCursor
onPressed: {
window.startSystemResize(Qt.TopEdge);
}
}
}
Rectangle {
id: resizeRectangleBottom
color: "yellow"
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: resizeRectangleSize
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: containsMouse ? Qt.SizeVerCursor : Qt.ArrowCursor
onPressed: {
window.startSystemResize(Qt.BottomEdge);
}
}
}
Rectangle {
color: "orange"
anchors.left: parent.left
anchors.right: parent.right
anchors.top: resizeRectangleTop.bottom
height: moveRectangleSize
MouseArea {
anchors.fill: parent
onPressed: {
window.startSystemMove();
}
}
}
}
P. S. И, конечно, благодарю за поднятую на форуме тему 🤝



