LINUX.ORG.RU

Qt4: Обработка события перемещения


0

0

Добрый день!

Не могу понять как обработать событие перемещения виджета. Как следует из документации (и из экспериментирования ) moveEvent() посылается только при перемещении виджета относительно родителя. А что если мне нужно позиционировать popup окно (наподобие меню), которое должно изменять положение при перемещении главного окна (естественно при этом виджет, за которым должно следовать popup окно относительно главного окна не движется). Кто-нибудь знает как это сделать? Заранее благодарен.

Ответ на: комментарий от Torvus

А если несколько родителей — в смысле не прямых родителей Ну например, я открываю ComboBox, после этого могу перемещать тулбар на котором он расположен или главное окно, а выпадающий список этого ComboBox'a всегда следует за самим ComoBox'ом.

По сути, мне нужен виджет, который работает так же как ComboBox, но содержит не текст с иконками, а картинки и некоторый дополнительный функционал. Наследую я от класса QWidget и реализую вручную все необходимые методы. Вопрос в том, как мне добиться такого же поведения моего всплывающего меню, какое у ComboBox я описал в предыдущем абзаце. Обычно это реализуется за счет переопределения в самом меню обработчика события перемещения окна родителя. Какой метод в этом меню при этом вызывается, или какое событие из enum QEvent::Type за это отвечает?

ars_ibr
() автор топика
Ответ на: комментарий от ars_ibr

>Обычно это реализуется за счет переопределения в самом меню обработчика события перемещения окна родителя

На сколько я помню, меню ничего не знает об изменении положения родителя. Это родитель при своем перемещении говорит меню переместиться вслед.

Torvus
()
Ответ на: комментарий от Torvus

Ну да, ошибся, даже скорее, описался :) Я имел ввиду именно это. Суть в том, что родитель не может получить этой информации (точнее я не знаю как ее получить). Не могу же я у всех родительских окон начиная с MainWindow переопределять moveEvent() чтобы он вызывал moveEvent() дочерних окон. Мне кажется, что это как-то можно включить, ну или есть другой обработчик, который это позволяет делать.

ars_ibr
() автор топика
Ответ на: комментарий от ars_ibr

>нужен виджет, который работает так же как ComboBox, но содержит не текст с иконками, а картинки и некоторый дополнительный функционал

Так задай ему делегат, и рисуй там всё что хочешь. Если основная кнопка тоже должна показывать что-то - наследуй QComboBox и переопределяй paintEvent.

summatus
()
Ответ на: комментарий от ars_ibr

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

Torvus
()
Ответ на: комментарий от ars_ibr

>Не могу же я у всех родительских окон начиная с MainWindow переопределять moveEvent()

Ставь фильтры событий.

summatus
()
Ответ на: комментарий от name_no

И на всех ставить фильтры? Что-то я сомневаюсь, что ComboBox так делает :) И притом, какое событие из QEvent::Type отслеживать? Кстати говоря, идеалогически фильтр событий мало отличается от банального переопределения, только реализуется удобнее и все, а так, те же яйца, только в профиль..

ars_ibr
() автор топика
Ответ на: комментарий от arsi

А если несколько родителей — в смысле не прямых родителей Ну например, я открываю ComboBox, после этого могу перемещать тулбар на котором он расположен или главное окно, а выпадающий список этого ComboBox'a всегда следует за самим ComoBox'ом.

installEventFilter в зубы и вперёд. Позволяет одним объектам перехватывать события от других.

Gorthauer ★★★★★
()
Ответ на: комментарий от Gorthauer

А на какое событие из enum QEvent::Type фильтр ставить, которое из них за перемещение отвечает?

ars_ibr
() автор топика
Ответ на: комментарий от ars_ibr

>я открываю ComboBox, после этого могу перемещать тулбар на котором он расположен или главное окно

Флип комбобокса это попап окно, то есть при потери фокуса оно должно закрыться, имхо, стандартное и правильное поведение. Как ты собираешься таскать парента не закрывая попап? Или как ты собираешься закрывать попап? Выбирая значение или кликая только по комбобоксу, неудобно и нестандартно.

zJes ★★
()
Ответ на: комментарий от zJes

Согласен! Очень правильное замечание! Что-то я об этом не подумал :) Но все же интересно услышать ответ ни последний вопрос, раз уж он возник!

ars_ibr
() автор топика
Ответ на: комментарий от ars_ibr

> А на какое событие из enum QEvent::Type фильтр ставить, которое из них за перемещение отвечает?

QEvent::Move :)
Если я правильно тебя понял, то я бы плясал от парента с потомку, у комбобокса одновременно не может быть открыто больше одного попапа. Следовательно при перемещении (moveEvent) таскать еще и попап не составит труда. То есть тут можно достаточно просто и без фильтров все делать.

zJes ★★
()
Ответ на: комментарий от zJes

QEvent::Move оно же moveEvent() вызывается ТОЛЬКО при перемещении этого окна в родительском, то есть, как я уже проверил, ТОЛЬКО при вызове move(). Если перемещать главное окно полностью, то положение ComboBox относительно него (в локальных координатах) не меняется и значит и событие это НЕ возникает :)

ars_ibr
() автор топика
Ответ на: комментарий от ars_ibr

Ай, ну да, прогнал. Подобное делал, но там было проще, попапы и тд я привязывал к графиксцене, то есть тут задармо был подобный эффект. Тут вероятно можно сделать вот так, криво конечно, (код примерный)

while(parent = parent()){
    installEventFilter(parent)
}

bool eventFilter(obj, event){
   if (event->type() == QEvent::Move){
      pos = mapToGlobal(parent(), pos())... // как там сам решишь
   }
   return QObject.eventFilter(obj, event)
}

zJes ★★
()
Ответ на: комментарий от zJes

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

А при обработке рекурсия пойдет вниз :) Ладно, не буду о грустном, спасибо за код :)

ars_ibr
() автор топика
Ответ на: комментарий от ars_ibr

Если честно, то такие вещи я не встречал даже в использовании, обычно или доки или диалоги.

И я не понял, что ты имел ввиду под «А при обработке рекурсия пойдет вниз»?

zJes ★★
()
Ответ на: комментарий от zJes

Да просто чрезвычайно медленный механизм обработки всего этого в Qt. Обработчики можно в 4 местах перегружать, событие поступает окну, потом идет вниз по иерархии и на каждом этапе идет проверка что это за сообщение в switch'e, да еще мало того, каждый раз проверяется есть ли зарегестрированный обработчик, если он есть, то вызывается, получается такая громадина... Оно конечно помогает быстро делать программы, но столько ресурсов зря расходует...

ars_ibr
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.