Как сделать так, чтобы Qt Windows оставался липким и действовал как одно окно? - PullRequest
4 голосов
/ 23 сентября 2011

Я пытаюсь реализовать сценарий, в котором два окна Qt будут располагаться рядом, и они будут немного липкими друг к другу.Перетаскивая один из них, другой также перетаскивается.Даже при выполнении alt-tab они должны вести себя как одно окно.

Любая помощь или указатель будут чрезвычайно полезны.

-Soumya

Ответы [ 3 ]

3 голосов
/ 23 сентября 2011

То, что вы описываете, звучит так, как будто оно подходит для сценария "стыковки". Вы, вероятно, наиболее знакомы с стыковкой с панелей инструментов; где вы можете либо перемещать панель инструментов самостоятельно, либо прикреплять ее к любому краю окна приложения. Но у Qt есть более обобщенный механизм:

http://doc.qt.io/qt-5/qtwidgets-mainwindows-dockwidgets-example.html

http://doc.qt.io/qt-5/qdockwidget.html

Это не тот случай, когда несколько окон верхнего уровня перемещаются синхронно со своими собственными заголовками и т.п. Окна верхнего уровня будут объединены в одно содержащее окно, когда они должны стать «липкими». Но IMO это более элегантно практически для любой ситуации и обеспечивает свойства, которые вы, похоже, ищете.

1 голос
/ 23 сентября 2011

Установите фильтр событий в отслеживаемом окне с помощью QObject::installEventFilter() и установите фильтр на QEvent::Move

После этого вы можете изменить положение окна отслеживания при каждом вызове фильтра с этим типом события.

0 голосов
/ 14 октября 2018

Я нашел способ привязки двух окон: когда пользователь перемещает окно, другое следует, сохраняя его относительное положение с перемещенным.

Это немного хак, потому что предполагаетчто событие 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

...