Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: darronОтветов: 6

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

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

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

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

Есть ли независимый от ОС способ быть прозрачным для событий клавиатуры?

ИЗМЕНИТЬ:

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

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

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

  • понятия не имею, почему кто-то проголосовал за этот ... совершенно законный вопрос. к сожалению, у меня нет ответа, но я почти уверен, что он есть, потому что, если я правильно помню, в KDE есть такие виджеты на рабочем столе, и он основан на Qt. Idan K 16.06.2009
  • Вы когда-нибудь находили решение для Linux? nilshi 08.04.2014

desktop-applicationqtevent-handling

Ответы

Ответ 1 · рейтинг 11 · JProgrammer

В 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 · рейтинг 11 · mx1up

Я нашел следующее решение (проверено на Linux, также работает на Windows согласно @TheSHEEEP):

setWindowFlags(windowFlags() | Qt::WindowTransparentForInput);

Он был добавлен в более позднем выпуске qt (я не нашел, когда) см. http://doc.qt.io/qt-5/qt.html

Ответ 3 · рейтинг 8 · Marc Mutz - mmutz

Может быть, то, что вы хотите, это

widget->setAttribute(Qt::WA_TransparentForMouseEvents)

? Это то, что использует QRubberBand, чтобы родительский элемент мог обрабатывать события мыши. Что касается событий клавиатуры, QWidget не получает никаких событий клавиатуры, если только он не установил для себя focusPolicy().

setFocusPolicy( Qt::NoFocus );

поэтому следует позаботиться о событиях клавиатуры.

Ответ 4 · рейтинг 2 · Joe Corkery

Возможно, я что-то упустил, но пробовали ли вы создать подкласс класса QMainWindow и переопределить QWidget Метод ::event() всегда возвращает false? Если вам нужно обрабатывать какие-то события, вы также можете добавить эту информацию сюда.

Этот метод должен позволить вам проверять события, поступающие в приложение, и игнорировать их, если это необходимо, без необходимости их использования с помощью фильтра событий.

Если это не сработает, вы можете попытаться перенаправить события на рабочий стол, вызвав QCoreApplication: :notify() и передать событие виджету рабочего стола, полученному путем вызова QApplication ::рабочий стол(). Я понятия не имею, сработает ли это, но мне показалось, что стоит попробовать.

Ответ 5 · рейтинг 1 · Maleev

Я думаю, что переопределение должно работать:

bool YourMainWindow::event( QEvent *event )
{
   event ->accept();
   return true;
}

это часть того, что документация класса QWidget говорит о функции-члене event():

Эта функция возвращает значение true, если событие было распознано, иначе - значение false. Если распознанное событие было принято (см. QEvent::accepted), любая дальнейшая обработка, например передача события родительскому виджету, прекращается.

Ответ 6 · рейтинг 1 · Krsna

Используйте фильтры событий 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);
}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы