Qt - виджет верхнего уровня с прозрачностью событий клавиатуры и мыши?
Я хочу приложение главное окно, чтобы игнорировать события мыши и клавиатуры, передавая их приложениям под ним в Z-порядке оконного менеджера.
Я вижу, как заставить дочерние виджеты игнорировать события клавиатуры или мыши, но как насчет главного окна?
Я пытаюсь создать виджет рабочего стола, который всегда сидит поверх фона и полностью невидим для событий клавиатуры и мыши. (Пройти)
Qt:: X11BypassWindowManagerHint получает пропуск через клавиатуру (хотя, к сожалению, X11 специфичен, но сейчас прекрасен), так как насчет событий мыши?
Есть ли способ, способный к OS-агности, быть прозрачным для событий клавиатуры?
EDIT:
Ключевым словом здесь является прозрачность.
Я не хочу EAT мыши и клавиатурные события, я хочу, чтобы оконный менеджер знал, что я не хочу их вообще. Эти события должны быть направлены на любое приложение, находящееся под мной в zorder.
Например, я хочу иметь возможность нажимать на значки на рабочем столе, которые покрываются моим виджетами, и взаимодействовать с ними, как будто виджета там не было.
Ответы
Ответ 1
В Windows вы можете установить WS_EX_TRANSPARENT
Для этого в Qt используйте следующий код:
Включить заголовок,
#if _WIN32
#include <windows.h>
#endif
и поместите следующий код в конструктор.
#if _WIN32
HWND hwnd = (HWND) winId();
LONG styles = GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, styles | WS_EX_TRANSPARENT);
#endif
Ответ 2
Возможно, вам нужно
widget->setAttribute(Qt::WA_TransparentForMouseEvents)
? То, что использует QRubberBand, чтобы позволить родителям обрабатывать события мыши. Что касается событий клавиатуры, QWidget не получает никаких событий клавиатуры, если только он не установил focusPolicy().
setFocusPolicy( Qt::NoFocus );
должен заботиться о событиях клавиатуры.
Ответ 3
Я нашел следующее решение (протестированное на Linux, также работает на Windows в соответствии с @TheSHEEEP):
setWindowFlags(windowFlags() | Qt::WindowTransparentForInput);
Он был добавлен в более позднюю версию Qt (я не нашел, когда)
см. http://doc.qt.io/qt-5/qt.html
Ответ 4
Возможно, мне что-то не хватает, но вы пробовали подклассифицировать класс QMainWindow и переопределить метод QWidget:: event() для всегда возвращать false? Если вам нужно обработать некоторые события, вы также можете добавить этот интеллект.
Этот метод должен позволять вам проверять события, входящие в приложение, и игнорировать их, если это необходимо, без необходимости их использовать с помощью фильтра событий.
Если это не сработает, вы можете попытаться перенаправить события на рабочий стол, вызвав QCoreApplication:: notify() и передав событие в виджет рабочего стола, полученный путем вызова QApplication:: desktop(). Я не знаю, будет ли это работать, но казалось, что стоит попробовать.
Ответ 5
Я думаю, что переопределение должно работать:
bool YourMainWindow::event( QEvent *event )
{
event ->accept();
return true;
}
что некоторые из того, что документация класса QWidget говорит о функции члена():
Эта функция возвращает значение true, если событие было признано, в противном случае возвращает false. Если распознанное событие (см. QEvent:: принято), любая дополнительная обработка, такая как событие распространение родительского виджета останавливается.
Ответ 6
Используйте Qt фильтры событий: они позволят вашему приложению есть какие-либо события, которые вы указали (например, события клавиатуры и мыши), но все еще обрабатываете другие события, такие как события рисования.
bool FilterObject::eventFilter(QObject* object, QEvent* event)
{
QKeyEvent* pKeyEvent = qobject_cast<QKeyEvent*>(event);
QMouseEvent* pMouseEvent = qobject_cast<QMouseEvent*>(event);
if (pKeyEvent || pMouseEvent)
{
// eat all keyboard and mouse events
return true;
}
return FilterObjectParent::eventFilter(object, event);
}