Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt GUI _ Обработка события клика НЕ на виджете

Автор: ars 19.4.2010, 20:35

Добрый день! Пишу собственный виджет. Не пойму как обработать событие клика не на этом виджете. Условно говоря, мой виджет встраивается в панель в главном окне приложения, при клике НЕ на нем, то есть на любой другой области внутри этого главного окна или даже вне этого главного окна, должно производиться некоторое действие. В качестве примера подобного функционала можно привести закрытие в ComboBox'е списка при клике на любую часть экрана. Пробовал ставить фильтр события на все родительские окна, во первых очень коряво получается, а во вторых, при этом не получается обрабатывать клик на неродительские окна (соседние в дереве окон). Кто-нибудь знает как можно это реализовать?

Автор: Litkevich Yuriy 19.4.2010, 21:38

Цитата(ars @ 20.4.2010, 0:35) *
закрытие в ComboBox'е списка при клике на любую часть экрана.
это событие потери фокуса, для общего случая на него не стоит ориентироваться

задача вроде сформулирована чётко, однако откуда растут ноги не понятно.
Что твой виджет собирается делать с событием "щелчок", которое будет иметь координату уходящую за пределы самого виджета?

Автор: ars 19.4.2010, 22:19

По поводу потери фокуса -- сомневаюсь. Простой пример, пользуюсь браузером Opera. Там есть панель адреса, если список в ней открыть, то она получает фокус, если после этого кликнуть на свободной части панели, то список закроется, но курсор все равно будет мигать в строке набора адреса, значит фокус не теряется :) И притом, а делать, если элемент не должен вообще фокус получать?


Хотя можно конечно обработать потерю фокуса так хитро, чтобы он не терялся :) Но что при этом делать с элементами у которых не должно быть фокуса -- не понятно...

Автор: Litkevich Yuriy 19.4.2010, 22:41

Цитата(ars @ 20.4.2010, 2:19) *
значит фокус не теряется
не теряется у кого? у выпадающего списка или поля ввода ;)

ты ответь на вопрос
Цитата(Litkevich Yuriy @ 20.4.2010, 1:38) *
Что твой виджет собирается делать с событием "щелчок", которое будет иметь координату уходящую за пределы самого виджета?
тогда и решение придёт быстрее.

Автор: ars 19.4.2010, 22:44

Он собирается перерисовываться и скрывать дочерние элементы :) Мне кажется, что поле представляет из себя со списком единый виджет, хотя кто знает разработчиков Opera :)

Автор: Litkevich Yuriy 19.4.2010, 22:52

Цитата(ars @ 20.4.2010, 2:44) *
Он собирается перерисовываться и скрывать дочерние элементы
ну тогда, могу такой вариант предложить, коль скоро фокуса может вовсе не иметь:
1) Использовать стороннюю библиотеку Qxt, в ней есть глобальная работа с событиями клавиатуры и мыши

2) с использованием только Qt, не уверен, что получится
a)в своём виджете заполучить указательна окно, в котором он помещён (циклически перебрать родителей)
b )узнать у окна геометрию
c)наложить на окно прозрачный виджет
d)сделать этот виджет одновременно и прозрачным для мыши и обрабатывающим события мыши (не уверен в этом месте, возможны ли оба варианта)

Автор: ars 19.4.2010, 22:57

0.о
Кошмар :)

Интересно, стоит считать эти 2 варианта несовершенством Qt или просто отсутствием необходимости делать то, что я предложил....

Автор: BRE 20.4.2010, 7:09

Если хочется получать все события от мышки, даже когда она за пределами виджета, то посмотри на:
void QWidget::grabMouse ()

Так же советую посмотреть как подобный функционал реализован в Qt, например, как это сделано у QToolTip или QComboBox.

Автор: kwisp 20.4.2010, 7:38

ars,
к предложенному варианту BRE

Цитата(BRE @ 20.4.2010, 8:09) *
Если хочется получать все события от мышки, даже когда она за пределами виджета, то посмотри на:
void QWidget::grabMouse ()

можно добавить обработку события покидания виджета - leaveEvent(QEvent*)
получается сможешь поймать щелчок за пределами виджета простой установкой флага в leaveEvent(QEvent*)


Автор: Litkevich Yuriy 20.4.2010, 10:03

Цитата(kwisp @ 20.4.2010, 11:38) *
можно добавить обработку события покидания виджета - leaveEvent(QEvent*)
получается сможешь поймать щелчок за пределами виджета простой установкой флага в leaveEvent(QEvent*)
если я правильно понял автора, то у него виджет изначально не в фокусе и мышь в нём бывает редко, но некие действия должны происходить именно по щелчку мыши. Т.е. leaveEvent(QEvent*) уже отработал, но это ни к чему не должно приводить

Автор: kwisp 20.4.2010, 11:09

Цитата(Litkevich Yuriy @ 20.4.2010, 11:03) *
Т.е. leaveEvent(QEvent*) уже отработал, но это ни к чему не должно приводить

я это и имел ввиду.
в leaveEvent(QEvent*) устанавливать флаг - мышь за пределами виджета
в enterEvent(QEvent*) сбрасывать.
grabMouse() передаст щелчки мыши в желаемый виджет,
в обработчиках щелчков мы будем проверять флаг и в соответсвии со значением действовать.

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)