Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: SASA от Июнь 03, 2008, 16:53



Название: Окно «прозрачное» для мыши.
Отправлено: SASA от Июнь 03, 2008, 16:53
Всем здравствуйте.
Есть два окошка, имеющих одного родителя. Располагаются одно над другим. Как сделать верхнее «прозрачным» для мыши. Т.е. при клике не верхнем событие приходит нижнему.


Название: Re: Окно «прозрачное» для мыши.
Отправлено: uriel от Июнь 03, 2008, 16:58
Код:
void QObject::installEventFilter ( QObject * filterObj )
Installs an event filter filterObj on this object. For example:
     monitoredObj->installEventFilter(filterObj);
An event filter is an object that receives all events that are sent to this object. The filter can either stop the event or forward it to this object. The event filter filterObj receives events via its eventFilter() function. The eventFilter() function must return true if the event should be filtered, (i.e. stopped); otherwise it must return false.
Только координаты мышки транслировать придётся.


Название: Re: Окно «прозрачное» для мыши.
Отправлено: Sergeich от Июнь 03, 2008, 17:00
Ставь на первое событийный фильтр и в нем переправляй мышиные события второму через QApplication::postEvent


Название: Re: Окно «прозрачное» для мыши.
Отправлено: SASA от Июнь 03, 2008, 17:09
Я заранее не знаю какие окошки где находятся. Под верхним могут лежать два, три, пять окошек! И надо передать событие именно тому, которое непосредственно под верхним. Как определить Z-order окошка? Как понять какие окошки находятся в конкретной точке.


Название: Re: Окно «прозрачное» для мыши.
Отправлено: Alex03 от Июнь 04, 2008, 06:13
SASA А зачем такое может понадобиться?
Или это верхнее окошко полупрозрачное?

Может можно обойтись изменением геометрии (на нечто отличное от прямоугольника) этого верхнего окна с помощью void QWidget::setMask() ?
Цитировать
Masked widgets receive mouse events only on their visible portions.


Название: Re: Окно «прозрачное» для мыши.
Отправлено: SASA от Июнь 04, 2008, 12:25
Окошко не прозрачное в смысле регионов. Это окошко эмулирует тень. Просто залито цветом с альфа каналом. Т.е. нижнее окошко видно, но, мышь до него не доходит.


Название: Re: Окно «прозрачное» для мыши.
Отправлено: Alex03 от Июнь 04, 2008, 13:37
А так:
Код:
setAttribute(Qt::WA_TransparentForMouseEvents);

PS Qt::WA_TransparentForMouseEvents - почему-то нет в хэлпе (по крайней мере в 4.3.3) :(


Название: Re: Окно «прозрачное» для мыши.
Отправлено: SASA от Июнь 15, 2008, 13:59
Всем спасибо за ответы! Особенно Alex03.
Действительно, флаг Qt::WA_TransparentForMouseEvents делает окно прозрачным для кликов мышки. Но MouseMove не проходит, да и курсор отображается не нижнего окошка. Покопавшись в исходных кодах Qt, стало понятно, что  Qt::WA_TransparentForMouseEvents делает окно незаметным для функции QApplication ::widgetAt(). Это делает задачу поиска нижележащего окошка довольно простой.
Если точно знать название класса тени, то можно перекрыть функцию QApplication::notify(), и в ней перераспределить сообщения. Теперь наше окошко действительно "прозрачное".
Код:
bool CMyApp::notify ( QObject * receiver, QEvent * event )
{
if (receiver->inherits("CShadowWidget")) // сообщение пришло тени
{
if (event->type() == QEvent::MouseMove)  // и по ней двигается мышка
{
QPoint p = ((QMouseEvent*)event)->globalPos();
QWidget* newReceiver = widgetAt(p); // найдём того, кто лежит под тенью
if (newReceiver) // а таки лежит
{
((QWidget*)receiver)->setCursor(newReceiver->cursor()); // поставим на тени курсор от ниже лежащего
receiver = newReceiver; // переправим событие нижележащему
}
}
}
return QApplication::notify(receiver,event);
}