- 1. main.qml
If for some reason, you decide to abandon the standard system window frame and implement all the Title Bar windows on your own in QML, then you can easily implement this with QML, which is even easier than in C ++, in my opinion. For acquaintance you can look at the article on customization of the application window in the AIMP style . There is a significant amount of code for implementing the mechanics of moving the window, as well as its resize. The advantage of QML in this case is that QML immediately provides the layout of the application, so you can use MouseArea and anchors to immediately determine the desired processing when clicking and moving the mouse without any special calculation of the cursor position in the window area.
And the mechanics of calculating the change in size and position will be similar to the one used in the article on customizing the application in C ++. That is, it will be necessary to remember the position where the mouse button was pressed, and then, relative to this position, make a resize and move the application window until the button is released.
As you can see in the figure above, you will need to create 5 MouseArea regions, four of which will be responsible for application resizing, and the fifth central for the application migration. That is, you can move the application by holding the mouse button anywhere in the fifth central area.
If you need a special Title Bar, then it can also be responsible for moving the application window. That is, it is not necessary to make the entire central region sensitive to movement.
main.qml
The application is created by default and only the main.qml file will be changed, which I will give as an example.
import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 ApplicationWindow { id: mainWindow visible: true width: 640 height: 480 flags: Qt.FramelessWindowHint // Disable window frame // Declare properties that will store the position of the mouse cursor property int previousX property int previousY MouseArea { id: topArea height: 5 anchors { top: parent.top left: parent.left right: parent.right } // We set the shape of the cursor so that it is clear that this resizing cursorShape: Qt.SizeVerCursor onPressed: { // We memorize the position along the Y axis previousY = mouseY } // When changing a position, we recalculate the position of the window, and its height onMouseYChanged: { var dy = mouseY - previousY mainWindow.setY(mainWindow.y + dy) mainWindow.setHeight(mainWindow.height - dy) } } // Similar calculations for the remaining three areas of resize MouseArea { id: bottomArea height: 5 anchors { bottom: parent.bottom left: parent.left right: parent.right } cursorShape: Qt.SizeVerCursor onPressed: { previousY = mouseY } onMouseYChanged: { var dy = mouseY - previousY mainWindow.setHeight(mainWindow.height + dy) } } MouseArea { id: leftArea width: 5 anchors { top: topArea.bottom bottom: bottomArea.top left: parent.left } cursorShape: Qt.SizeHorCursor onPressed: { previousX = mouseX } onMouseXChanged: { var dx = mouseX - previousX mainWindow.setX(mainWindow.x + dx) mainWindow.setWidth(mainWindow.width - dx) } } MouseArea { id: rightArea width: 5 anchors { top: topArea.bottom bottom: bottomArea.top right: parent.right } cursorShape: Qt.SizeHorCursor onPressed: { previousX = mouseX } onMouseXChanged: { var dx = mouseX - previousX mainWindow.setWidth(mainWindow.width + dx) } } // The central area for moving the application window // Here you already need to use the position both along the X axis and the Y axis MouseArea { anchors { top: topArea.bottom bottom: bottomArea.top left: leftArea.right right: rightArea.left } onPressed: { previousX = mouseX previousY = mouseY } onMouseXChanged: { var dx = mouseX - previousX mainWindow.setX(mainWindow.x + dx) } onMouseYChanged: { var dy = mouseY - previousY mainWindow.setY(mainWindow.y + dy) } } }
Огромное спасибо
Драсте, спасибо за хороший урок.
Это скорее всего баг Qt под конкретной операционной системой. Какую используете?
Дело в том, что я проверил Ваш код под свой рабочей системой (KDE Neon 5.8) и всё работает стабильно, без нареканий. То есть минимизация окна происходит без проблем. Под Windows проверить не могу, на данный момент у меня нет рабочих установок этой системы.
Использую Windows 7 Ultimate.
Тогда это однознано баг, я бы глянул на официальном багтрекере Qt, есть ли информация об этом баге, и возможно стоит создать таск с этим багом.
Спасибо! Этим и займусь. Ещё попробую скинуть проект другу, посмотрю, как QT будет справляться там.
После отключения системного обрамления не работают minimumHeight и minimumWidth. Что делать?
Задать свои property в окне и проверять их в методах изменения размера для topArea, bottomArea, rightArea, leftArea.
Еще не могли бы подсказать как сделать чтобы отображалась иконка, так как она тоже исчезла. Весь интернет обыскал так и не нашел решения.
Какая иконка? Которая была в оформлении окна? Ну всё логично, оформление отключили - иконка исчезла. Хотите иконку, придётся самосттоятельно добавить её в левый верхний угол окна через какой-нибудь QML тип Image.
Извиняюсь за не точность. Я имел в виду иконку в Taskbar.
Вы же под Windows пишете? Есть такой класс QWinTaskbarButton, у него есть property overlayIcon . Возможно, стоит поработать с этим клсассом и установить туда иконку. Вот в этой статье есть пример работы с этим QWinTaskbarButton .
Огромное спасибо, работает.
Я бы вместо совытий mouseXChanged и mouseYChanged использовал positionChanged, так как у двух первых есть один недостаток, они производные от mouseX и Y которые содержат текущие координаты X и Y соответсвенно - это значит что они обновляются (записываются) регулярно при нажатой кнопки мыши (если свойство hoverEnabled будет true то они будут обновляться и без нажатия кнопок мыши). Это значит, что эти свойства вызывают ложную логику, если вы еще не двигали курсор мыши, а просто нажали кнопку мыши. В то время как positionChanged срабатывает только когда положение курсора в действительности было изменено при нажатой кнопки мыши (если hoverEnabled = false, опять же).
Здравствуйте. Сделал подобным образом ресайз и в Qt Widgets, и в QML. Везде получаю, что при изменении размера через левую или верхннюю границы проихсодит мерцание подобно как на этом видео . Всё перелопатил, нигде ответа не нашел. Не знаете как это победить?
Добрый день. Нет, если сами по себе координаты при ресайзе все подсчитываются правильно, то это уже проблема графической подсистемы в ОС и работы с X11, если вы конечно под Linux собирали проект. В том видео в исходниках крутят платформозависимые флаги. На тему тех флагов есть Bug на багтрекере Qt . Возможно также локальная проблема с конкретным дистрибутивом, если на мейнстримовых дистрибутивах всё работает хорошо. В общем скорее всего это та помойка, в которой не хотелось бы копаться.