2009-06-12 5 views
35

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

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

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

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

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

EDIT:

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

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

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

+0

Ухх ... почему голос? – darron

+0

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

+0

Вы когда-нибудь находили решение для Linux? – nilsge

ответ

1

Я думаю, что наиважнейшая должен работать:

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

, что какая-то из того, что сказано в документации класса QWidget о событии() функции-члена:

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

1

Использование Qt-х event filters: они позволяют вашему приложению есть в зависимости от того события, вы указываете (т.е. события клавиатуры и мыши), но по-прежнему обрабатывать другие события, такие как краски событий.

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); 
} 
2

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

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

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

7

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

widget->setAttribute(Qt::WA_TransparentForMouseEvents) 

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

setFocusPolicy(Qt::NoFocus); 

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

+1

Хорошо, это именно то, что я сказал, я уже знаю, как это сделать. Я не хочу, чтобы виджет позволял «родителям обрабатывать события мыши» ... Я хочу, чтобы вся APPLICATION игнорировала их. Я хочу что-то сказать среде окон (X, WinXP и т. Д.), Чтобы щелчок на моем приложении должен просто перейти к другому приложению, расположенному под ним в Z-порядке. То, что набрав на клавиатуре, должно сделать то же самое. Эти решения просто передают события от дочерних виджетов родителям. Я хочу, чтобы события отправлялись из родительского виджета обратно в оконный менеджер или, скорее всего, просто никогда не отправлялись в приложение вообще. – darron

+0

Однако этот ответ полезен кому-то, кто действительно может сделать то, о чем вы говорите. (передать материал клиенту). Я попробовал это, случайно, что структура Qt действительно распознает, что вы пытаетесь игнорировать события на родительском уровне и пытаетесь отправить их обратно в диспетчер окон (или установите какой-то флаг в диспетчере окон, чтобы обойти) ... но, как и ожидалось, это не сработало. Мое приложение использовало события. – darron

+0

Верно, извините. С тех пор я также попробовал setMask(), который делает то, что вы хотите, но также и видимость клипов. Я почти уверен, что вы не можете делать то, что хотите, не отступая от ОС-хакеров. Вы нашли функциональность, которую ищете в любом другом приложении? –

10

В 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 
+0

Ничего себе !!! Оно работает. :) Большое спасибо JProgrammer. (+1) – zeFree

3

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

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

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

+1

Также работает на Windows. – TheSHEEEP

+0

спасибо за тестирование @TheSHEEEP – mxttie

Смежные вопросы