Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: kuzmich от Февраль 15, 2011, 16:16



Название: Отключить Popup закрытие при клике в другое окно
Отправлено: kuzmich от Февраль 15, 2011, 16:16
Есть окно с QLineEdit в котором вываливается popup список при начале ввода. И есть одновременно возникающее окно виртуальной клавиатуры, при нажатии на кнопки в которой в поле QLineEdit посылается insert(Qt::Key_1...0). Так проблема в том, что при вводе 3-х значного числа приходится нажимать 5 раз! из-за того, что каждое второе нажатие на виртуальное клаве съедается закрытием popup окна completer`а. F1! :)


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: GreatSnake от Февраль 15, 2011, 16:19
Скорее всего не получится, т.к. при таком popup-e делается граб.


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: kuzmich от Февраль 15, 2011, 16:28
Пытался отловить события с помощью eventFilter(), что-то ни фига не получилось. Не связаны ли такого рода события с оконным менеджером? Если да, то как их поймать?


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: GreatSnake от Февраль 15, 2011, 16:47
Цитировать
Не связаны ли такого рода события с оконным менеджером? Если да, то как их поймать?
Вполне возможно, что через NET_WM и в этом случае просто так вы их не поймаете.

А QLineEdit и "виртуальная клавиатура" это виджеты одного приложения?


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: GreatSnake от Февраль 15, 2011, 17:05
Хотя нет, я не прав.
QCompleter для popup-а использует окна типа Qt::Popup, а в этом случае окна создаются с флагом OverrideRedirect, т.е. минуя WM.
См. QApplication::activePopupWidget():
Цитировать
A popup widget is a special top-level widget that sets the Qt::WType_Popup widget flag, e.g. the QMenu widget. When the application opens a popup widget, all events are sent to the popup. Normal widgets and modal widgets cannot be accessed before the popup widget is closed.

Т.е. скорее всего, что-то не так проверяете в eventFilter(). Кстати чей перегрузили?


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: pastor от Февраль 15, 2011, 17:33
А отключить автодополнение?


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: asvil от Февраль 15, 2011, 18:41
Вот так GUI нынче пошла... Знали ли эти студенты из ксерокса, насколько серьезно воспримут их придумку. "И будет нам компьютер образы рисовать, как будто художник на мольберте". А Вы не пробовали в popup еще табличку засунуть в каждую ячейку таблички еще комбобокс, а в него табличку....
Простите вырвалось, к Вам отношение никакого не имеет, просто на работе "интересные" задачи ставят.



Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: kuzmich от Февраль 15, 2011, 21:08
2GreatSnake:
Пытался установить ParentWindow::eventFilter родительского окна для popup`a полученного QCompleter::popup(), типо:
QAbstractItem* mypopup =  qcompleter->popup();
mypopup->installEventFilter(this); // функцию родителя использую для ловли событий
qcompleter->setPopup(mypopup);
 А в функции родиля eventFilter() выводил события, которые ловились, надеялся увидеть что-то типо потери фокуса. Но там только show и т.д.

2pastor:
а что даст отключение автодополнения? Мне же именно оно и нужно. Только, чтобы при переключении фокуса popup не съедало клик и не пропадало.

2 Филоненко Михаил:
а где вы сложность несусветную нашли? На устройстве с тачскрином нужно пальцами набрать код, расшифровка которого вываливается, подсказывая оператору. Вроде бы логично показать на экране виртуальную клаву :)


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: pastor от Февраль 15, 2011, 21:42
> а что даст отключение автодополнения? Мне же именно оно и нужно. Только, чтобы при переключении фокуса popup не съедало клик и не пропадало.

я подумал, что оно не нужно вовсе ))


Попробуй перед insert(Qt::Key_1...0) устанавливать фокус в QLineEdit


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: asvil от Февраль 15, 2011, 22:29
Вы уверены, что расшифровываемая информация должна быть выполнена в виде отдельного окна? Если я правильно понимаю принципы popup - это модальное окно, tooltip - не модальное.
Возможно focus proxy в чем-то поможет. Возможно поможет просмотр исходников QComboBox, я когда-то просто его копировал, для своих нужд.


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: kuzmich от Февраль 16, 2011, 09:18
Фокус устанавливаю, но проблема как раз в переключении фокуса на виртуальную клаву.

Хотелось бы, чтобы подсказка максимум на 10 элементов вываливалась именно из поля QLineEdit, а вот в отдельном окне как раз и не хочется. Хотя может и придется, если не победю траблу. А вот с tooltip, т.е. не модальным выпрыгивающим окном, может и идея. Похоже мне нужно сделать именно не модальное. Пойду пробовать...


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: GreatSnake от Февраль 16, 2011, 10:38
Перегружать нужно QCompleter::eventFilter().


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: kuzmich от Февраль 16, 2011, 11:10
Пробовал, но свойство съедания клика popup окном не удалось исключить. Может что-то не так делал....
По-моему нашел способ ловить все события в приложении. Установить eventFilter() на QApplication. Так я от максимизации окон избавился и сложно, но можно замутить блокировку потери фокуса popup окна. Буду рыть-ковырять далее...


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: GreatSnake от Февраль 16, 2011, 11:15
Цитировать
Пробовал, но свойство съедания клика popup окном не удалось исключить. Может что-то не так делал....
Странно, т.к. в QCompleter::eventFilter():
Код
C++ (Qt)
...
case QEvent::MouseButtonPress: {
...
if (!d->popup->underMouse()) { // прячем popup, если ткнули не на его окно
d->popup->hide();
return true;
}
}
...
 


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: kuzmich от Февраль 16, 2011, 15:03
И точно! Реимплементил QCompletter с функцией eventFilter(), получилось заблокировать скрытие popup окна. В самом начале начал с этого, невнимательно код почитал и начал другие пути искать. Блин :) Теперь осталось из этой функции сгенерировать событие для виртуальной клавы, чтобы она нажала кнопку. Делал postEvent("клава",Qt::MouseButtonClick), QMouseEvent... - либо никакого эффекта, либо какое-то зацикливание в заморозкой всего.


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: GreatSnake от Февраль 16, 2011, 15:20
А что, так не прокатывает?
Код
C++ (Qt)
bool YourQtCompleter::eventFilter( QObject *o, QEvent *e )
{
if( e->type() == QEvent::MouseButtonPress )
{
if( !popup()->underMouse() && virtKbd()->underMouse() )
return QObject::eventFilter( o, e );
}
return QtCompleter::eventFilter( o, e );
}
 


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: kuzmich от Февраль 16, 2011, 15:40
Нет. И это тоже пробовал. Никакой реакции. Пробовал так же передавать указатель на клаву, полученный другим путем, не через аргумент Object*. Заново буду читать event processing)


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: GreatSnake от Февраль 16, 2011, 15:46
А под отладчиком? Какой return отрабатывает в этом случае?


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: kuzmich от Февраль 17, 2011, 11:11
return в условии точно отрабатывает и возвращает false. Тем более, там Object* который в аргументе - QListView, а нужно послать *virtKbd.
 Пробовал и другие варианты:
Код:
QCoreApplication::sendEvent( virtKbd,event ); // ret - true
//or
QCoreApplication::postEvent( virtKbd,event );
QCoreApplication::sendPostedEvents ( virtKbd, event->type() );// зависает
//or
QObject::eventFilter( o, e );// ret - false
//or
QWidget::eventFilter(this, event ); //ret -  false
Что-то я малость тут не догоняю :)
Кстати, использую QtEmbedded 4.3...


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: GreatSnake от Февраль 17, 2011, 11:17
Боюсь не понял про другие варианты, но уверен, что постить события из eventFilter() не лучшая идея.
Вполне возможно, что у Qt может и крышу снести от этого.
И какой event постите/посылаете virtKbd?


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: kuzmich от Февраль 17, 2011, 11:27
Просто уже от того, что не получается по нормальному продвинуть дальше в методы родительского класса событие с измененным объектом, как вы предлагали, начал извращаться с разнообразием посыла событий. Чую, что вариант должен быть, чтобы пропустить нажатие клавиши. Получается, тут лечу, там калечу))


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: GreatSnake от Февраль 17, 2011, 12:28
После некоторых исследований могу заявить, что ничего у вас не получится :(
Как я уже указывал выше Qt c виджетами типа Qt::Popup при их show() делает для них псевдо-граб (см. QApplication::activePopupWidget() ).
И в итоге никакие манипуляции нам не помогут.
Единственное, что могу предложить, переписать QCompleter, в котором будет и список и ваша виртуальная клавиатура в одном окне.


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: kuzmich от Февраль 17, 2011, 13:14
Так если
Цитировать
all events are sent to the popup
, а в исходниках QCompleter на popup устанавливается фильтр QCompleter::eventFilter() и я переназначаю на свою функцию и, главное, она срабатывает, то вы думаете, что если я посылаю из нее событие дальше кому угодно(в моем случае нажатие пальцем на вирт. клаве), то событие снова перехватывается QCompleter::popup?!


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: GreatSnake от Февраль 17, 2011, 13:16
именно


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: kuzmich от Февраль 17, 2011, 13:22
блин побери ;D
Буду искать варианты...
Спасибо большое за советы!


Название: Re: Отключить Popup закрытие при клике в другое окно
Отправлено: kuzmich от Февраль 21, 2011, 16:01
Оказалось проще реализовать весь функционал в своем виджете(MyPopupWindow ). Но теперь из-за того, что он не имеет родителя, он может получить фокус. А окно должно быть только информативное, безо всякого взаимодействия с пользователем. В общем, теперь думаю, как перехватывать клик на нем... Попробовал:
Код:
QApplication app;
app.installeventFilter(globalObject);

GlobalObject::eventFilter(QObject *obj, QEvent *event)
{
    if( obj == MyPopupWindow && event->type() == Qt::MouseButtonPress ) //если кликнули в моем информационном окне
       {
           MyInputWindow->activateWindow(); //активировать фокус в окне ввода информации
           return true; //событие обработано
        }
}
получается ерунда какая то. Все ловится, но фокус теряется.