Я пытаюсь добиться того же эффекта, что и мини-плеер iTunes, когда изменение размера происходит в macOS. То есть определение, когда изменение размера окна было завершено, ЗАТЕМ изменение высоты на определенное значение. Вот наглядный пример:
Проблема в том, что в окне QML не существует сигнала, уведомляющего меня, когда оконный менеджер изменяет размер (то есть пользователь освобождает дескриптор). Следовательно, если у меня нет сигнала и я применяю изменение высоты, как только изменяется ширина или высота во время изменения размера, окно будет мерцать (происходит двойное изменение размера), пока пользователь не отпустит ручку.
Спасибо за любой вклад или помощь!
Я только что добавил это!
попробуйте сделать это на стороне С++: stackoverflow.com/questions/51223199/…
нет, мне нужен не размер окна, а момент, когда пользователь отпускает окно, а не момент, когда он изменяет размер окна, не отпуская его.
ОП, тебе удалось найти для этого встроенное решение?
Вы можете довольно легко реализовать свой собственный дескриптор изменения размера, используя MouseArea и обрабатывая окончательный расчет изменения размера с помощью onReleased (здесь высота должна составлять 75% ширины при выпуске):
Window {
id: window
flags: Qt.FramelessWindowHint
visible: true
height: 300
width: 400
MouseArea {
id: resize
anchors {
right: parent.right
bottom: parent.bottom
}
width: 15
height: 15
cursorShape: Qt.SizeFDiagCursor
property point clickPos: "1,1"
onPressed: {
resize.clickPos = Qt.point(mouse.x,mouse.y)
}
onPositionChanged: {
var delta = Qt.point(mouse.x-resize.clickPos.x, mouse.y-resize.clickPos.y)
window.width += delta.x;
window.height += delta.y;
}
onReleased: {
window.height = .75 * window.width
}
Rectangle {
id: resizeHint
color: "red"
anchors.fill: resize
}
}
}
Спасибо большое. Я думаю, что ваш ответ кажется более выполнимым в Qt. Это по-прежнему остается очень хакерским, так как означает потерю всех системных преимуществ (быстрое переключение между окнами, изменение размера углов, ...). Сначала я попробую этот подход, но не отмечайте ваш ответ как решение моего вопроса, поскольку он все еще не является идеальным, «максимально близким к нативному» решением.
QML предоставил несколько сигналов NOTIFY, когда предполагается обновить значения свойств. Таким образом, вы можете использовать Window.width
и Window.height
:
Window {
id: window
onWidthChanged: {
// Will be executed after window.width value changes.
}
onHeightChanged: {
// Will be executed after window.height value changes.
}
// Other window-related stuff
}
Спасибо за ответ, но это никак не решает мою проблему. На самом деле, я уже пробовал этот апроч, но мне особенно нужен сигнал, когда пользователь RELEASE дескриптор. Поскольку, если я принудительно изменю размер окна, как только пользователь прекратит изменение размера, но не перестанет удерживать ручку перетаскивания, а позже решит снова изменить положение, изменение размера изменило бы положение ручки, а новое изменение размера изменит размер окна снова к (последней) точке удержания. Конечный результат визуально очень неприятный!
Вот идея (которую я еще не пробовал, но все же):
Реализуйте обработчик событий, реагирующий на изменение глобальной позиции курсора. Положение курсора внутри окна неприменимо, так как курсор находится за пределами окна при захвате маркера изменения размера. Не уверен, возможен ли и как такой обработчик событий, но, по крайней мере, доступ к позиции курсора на экране — это возможно в Qt.
В обработчике событий проверьте, совпадает ли изменение положения курсора по вертикали по сравнению с последним вызовом обработчика с изменением высоты окна.
Вам, вероятно, придется преодолеть несколько проблем, таких как (1) допущение определенного расхождения между изменениями высоты окна и позиции курсора y, поскольку изменения высоты окна могут быть менее частыми и несколько следовать за движением курсора, (2) задействовать обработчик событий положения курсора только во время изменения размера окна, чтобы ограничить нагрузку на систему. Но если это работает, это собственное решение, не реализующее собственные ручки изменения размера.
Кажется, вы хотите, чтобы QML отправлял два разных типа сигналов: один для отметки начала и окончания изменения размера, а другой для отметки изменений размера во время изменения размера. Тогда последовательность событий будет примерно такой:
window.resizeStarted() // hypothetical new event
window.widthChanged()
window.heightChanged()
window.widthChanged()
window.heightChanged()
...
window.resizeEnded() // hypothetical new event
Это, по-видимому, невозможно в Qt из коробки, но вы должны быть в состоянии реализовать это самостоятельно с помощью этого подхода, изначально предназначенного для того, чтобы вообще не перекрашивать окно при изменении размера:
Filter the relevant events out until the mouse button has been released. Specifically, "eat" the resize event while the mouse button is held down, and then synthesize the final resize event once the mouse is released. You can do it all in an event filter attached to the window / widget object that displays your QML interface. (source)
Процесс будет очень похож на тот, что в цитате:
Расширьте тип окна QML с помощью пользовательских сигналов:
//MyWindow.qml
Window {
signal resizeStarted()
signal resizeEnded()
}
Создайте фильтр событий в окне QML, который "съедает" все события изменения размера окна. Когда он встречает первый, он отправляет resizeStarted()
. Затем он перенаправляет события изменения размера окна. Когда он сталкивается с событием отпускания мыши при изменении размера, он отправляет resizeEnded()
после последнего события widthChanged()
/ heightChanged()
.
Реализуйте соответствующий обработчик сигнала onResizeEnded
в QML, чтобы реагировать, здесь, чтобы адаптировать высоту окна вашего приложения к определенному фиксированному значению.
Мне это кажется довольно многообещающим маршрутом, но, к сведению, я пока не пробовал его в коде.
Можете ли вы добавить какой-нибудь наглядный пример этого эффекта (gif)?