Подтвердить что ты не робот

Qt - виджет верхнего уровня с прозрачностью событий клавиатуры и мыши?

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

Я вижу, как заставить дочерние виджеты игнорировать события клавиатуры или мыши, но как насчет главного окна?

Я пытаюсь создать виджет рабочего стола, который всегда сидит поверх фона и полностью невидим для событий клавиатуры и мыши. (Пройти)

Qt:: X11BypassWindowManagerHint получает пропуск через клавиатуру (хотя, к сожалению, X11 специфичен, но сейчас прекрасен), так как насчет событий мыши?

Есть ли способ, способный к OS-агности, быть прозрачным для событий клавиатуры?

EDIT:

Ключевым словом здесь является прозрачность.

Я не хочу EAT мыши и клавиатурные события, я хочу, чтобы оконный менеджер знал, что я не хочу их вообще. Эти события должны быть направлены на любое приложение, находящееся под мной в zorder.

Например, я хочу иметь возможность нажимать на значки на рабочем столе, которые покрываются моим виджетами, и взаимодействовать с ними, как будто виджета там не было.

4b9b3361

Ответ 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);
}