Я нашел способ привязки двух окон: когда пользователь перемещает окно, другое следует, сохраняя его относительное положение с перемещенным.
Это немного хак, потому что предполагаетчто событие QEvent::NonClientAreaMouseButtonPress
отправляется, когда пользователь щелкает левой кнопкой мыши на строке заголовка, удерживая ее нажатой, пока он перемещает окно, и освобождая ее в конце, так что QEvent::NonClientAreaMouseButtonRelease
отправлено.
Идея состоит в том, чтобы использовать обработчик событий QWidget::moveEvent
каждого окна для обновления геометрии другого, используя QWidget::setGeometry
.
Но в документации говорится, что:
Calling setGeometry() inside resizeEvent() or moveEvent() can lead to infinite recursion.
Поэтому мне нужно было запретить обработчику окон moveEvent
, который не был перемещен пользователем напрямую, обновитьгеометрия другого.
Я добился этого с помощью результата QObject::installEventFilter
, перехватывая суммированные события.
Когда пользователь нажимает на строку заголовка WindowOne
чтобы начать операцию перемещения, WindowOne::eventFilter
ловит ее QEvent::NonClientAreaMouseButtonPress
и устанавливает публичный атрибутte WindowTwo::skipevent_two
до true
.
Когда пользователь перемещается WindowOne
, WindowTwo::moveEvent
вызывается при операции setGeometry
, выполняемой на WindowTwo
с WindowOne::moveEvent
.
WindowTwo::moveEvent
проверяет WindowTwo::skipevent_two
, и, если это true
, возвращается без выполнения операции setGeometry
над WindowOne
, которая вызовет бесконечную рекурсию.
Как только пользователь отпустит левуюкнопка мыши, заканчивая операцию перемещения окна, WindowOne::eventFilter
перехватывает QEvent::NonClientAreaMouseButtonRelease
и устанавливает открытый атрибут WindowTwo::skipevent_two
в false
.
Те же действия выполняются, если пользователь щелкает заголовок строки WindowTwo
, на этот раз атрибут WindowOne::skipevent_one
устанавливается равным true
и не позволяет WindowOne::moveEvent
выполнить любую setGeometry
операцию с WindowTwo
.
Я считаю, что это решение далеко не чистое и пригодное для использования,Некоторые проблемы:
- Я не уверен, когда и почему отправляются
QEvent::NonClientAreaMouseButtonRelease
и QEvent::NonClientAreaMouseButtonRelease
, за исключением случая, рассмотренного выше. - Когда / если размер одного окна изменяется безВзаимодействие с пользователем или без соответствующих щелчков мышью от пользователя, вероятно, все пойдет по бесконечной рекурсии.
- Нет никакой гарантии, что эти события мыши будут отправлены таким же образом в будущем.
- Свободное место для более ...
Подтверждение концепции: https://github.com/Shub77/DockedWindows