Как получить сигнал, когда оконный менеджер изменяет размер окна в qt QML?

Я пытаюсь добиться того же эффекта, что и мини-плеер iTunes, когда изменение размера происходит в macOS. То есть определение, когда изменение размера окна было завершено, ЗАТЕМ изменение высоты на определенное значение. Вот наглядный пример:

enter image description here

Проблема в том, что в окне QML не существует сигнала, уведомляющего меня, когда оконный менеджер изменяет размер (то есть пользователь освобождает дескриптор). Следовательно, если у меня нет сигнала и я применяю изменение высоты, как только изменяется ширина или высота во время изменения размера, окно будет мерцать (происходит двойное изменение размера), пока пользователь не отпустит ручку.

Спасибо за любой вклад или помощь!

Можете ли вы добавить какой-нибудь наглядный пример этого эффекта (gif)?

magrif 22.05.2019 20:48

Я только что добавил это!

N.D. 23.05.2019 09:29

попробуйте сделать это на стороне С++: stackoverflow.com/questions/51223199/…

bardao 23.05.2019 18:09

нет, мне нужен не размер окна, а момент, когда пользователь отпускает окно, а не момент, когда он изменяет размер окна, не отпуская его.

N.D. 25.05.2019 13:42

ОП, тебе удалось найти для этого встроенное решение?

Curtwagner1984 10.11.2021 22:25
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
6
5
3 097
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Вы можете довольно легко реализовать свой собственный дескриптор изменения размера, используя 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. Это по-прежнему остается очень хакерским, так как означает потерю всех системных преимуществ (быстрое переключение между окнами, изменение размера углов, ...). Сначала я попробую этот подход, но не отмечайте ваш ответ как решение моего вопроса, поскольку он все еще не является идеальным, «максимально близким к нативному» решением.

N.D. 25.05.2019 12:38

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 дескриптор. Поскольку, если я принудительно изменю размер окна, как только пользователь прекратит изменение размера, но не перестанет удерживать ручку перетаскивания, а позже решит снова изменить положение, изменение размера изменило бы положение ручки, а новое изменение размера изменит размер окна снова к (последней) точке удержания. Конечный результат визуально очень неприятный!

N.D. 25.05.2019 12:33

Вот идея (которую я еще не пробовал, но все же):

  1. Реализуйте обработчик событий, реагирующий на изменение глобальной позиции курсора. Положение курсора внутри окна неприменимо, так как курсор находится за пределами окна при захвате маркера изменения размера. Не уверен, возможен ли и как такой обработчик событий, но, по крайней мере, доступ к позиции курсора на экране — это возможно в Qt.

  2. В обработчике событий проверьте, совпадает ли изменение положения курсора по вертикали по сравнению с последним вызовом обработчика с изменением высоты окна.

    • Если да, предположим, что пользователь по-прежнему держит дескриптор изменения размера окна, поэтому не настраивайте высоту окна.
    • Если нет, предположим, что пользователь отпустил ручку изменения размера окна и начал свободно перемещать курсор. Отрегулируйте высоту окна сейчас.

Вам, вероятно, придется преодолеть несколько проблем, таких как (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)

Процесс будет очень похож на тот, что в цитате:

  1. Расширьте тип окна QML с помощью пользовательских сигналов:

    //MyWindow.qml
    Window {
       signal resizeStarted()
       signal resizeEnded()
    }
    
  2. Создайте фильтр событий в окне QML, который "съедает" все события изменения размера окна. Когда он встречает первый, он отправляет resizeStarted(). Затем он перенаправляет события изменения размера окна. Когда он сталкивается с событием отпускания мыши при изменении размера, он отправляет resizeEnded() после последнего события widthChanged() / heightChanged().

  3. Реализуйте соответствующий обработчик сигнала onResizeEnded в QML, чтобы реагировать, здесь, чтобы адаптировать высоту окна вашего приложения к определенному фиксированному значению.

Мне это кажется довольно многообещающим маршрутом, но, к сведению, я пока не пробовал его в коде.

Другие вопросы по теме