Тут на форуме давеча возникла тема, которую также можно отнести к топовым, если оценивать по частоте возникновения данного вопроса. Поэтому я решил оформить ответ более развернуто, чем подразумевается в рамках форума. И пресловутый вопрос заключается в том, как на 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. И, конечно, благодарю за поднятую на форуме тему 🤝