Qt - 具有键盘和鼠标事件透明度的顶级小部件?

时间:2009-06-12 14:45:43

标签: qt event-handling desktop-application

我希望应用的主窗口忽略鼠标和键盘事件,并将它们传递到窗口管理器Z顺序下面的应用程序。

我看到如何让小部件忽略键盘或鼠标事件,但主窗口怎么样?

我正在尝试制作一个总是位于背景上的桌面小部件,对键盘和鼠标事件完全不可见。 (通过)

Qt :: X11BypassWindowManagerHint 让我通过键盘传递(虽然很遗憾X11具体,但现在很好),那么鼠标事件呢?

是否存在与操作系统无关的方式对键盘事件透明?

修改

这里的关键词是透明度。

我不想 EAT 鼠标和键盘事件,我希望窗口管理器知道我根本不需要它们。这些事件应该针对zorder中我的任何应用程序。

例如,我希望能够点击我的小部件所覆盖的桌面图标并与它们进行交互,就好像小部件不在那里一样。

6 个答案:

答案 0 :(得分:11)

在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

答案 1 :(得分:9)

我找到了以下解决方案(在Linux上测试,根据@TheSHEEEP在Windows上运行):

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

它已被添加到更新的qt版本中(我没有找到什么时候) 见http://doc.qt.io/qt-5/qt.html

答案 2 :(得分:8)

也许你想要的是

widget->setAttribute(Qt::WA_TransparentForMouseEvents)

?这就是QRubberBand使用它来让父母处理鼠标事件。对于键盘事件,QWidget不会获得任何键盘事件,除非它自己设置了focusPolicy()。

setFocusPolicy( Qt::NoFocus );
因此,

应该处理键盘事件。

答案 3 :(得分:2)

也许我在这里遗漏了一些东西,但您是否尝试过继承QMainWindow类并重写QWidget::event()方法以始终返回false?如果你需要处理一些事件,你也可以在这里添加这些情报。

此技术应该允许您检查进入应用程序的事件,并在需要时忽略它们,而不必使用事件过滤器来使用它们。

如果这不起作用,您可以尝试通过调用QCoreApplication::notify()将事件重定向到桌面,并将事件传递给通过调用QApplication::desktop()获得的桌面小部件。我不知道这是否有效,但似乎值得一试。

答案 4 :(得分:1)

我认为压倒一切应该有效:

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

这是QWidget类文档中关于event()成员函数的一些内容:

  

如果是,则此函数返回true   事件被认可,否则它   返回false。如果认可的事件   被接受(见QEvent ::接受),   任何进一步的处理,如事件   传播到父窗口小部件   停止。

答案 5 :(得分: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);
}