43

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

我看到了如何让小部件忽略键盘或鼠标事件,但是主窗口呢?

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

Qt::X11BypassWindowManagerHint让我通过键盘(虽然遗憾的是 X11 特定,但现在很好),那么鼠标事件呢?

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

编辑:

这里的关键词是透明度。

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

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

4

6 回答 6

12

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

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

它已在最近的 qt 版本中添加(我没有找到时间)请参阅http://doc.qt.io/qt-5/qt.html

于 2016-08-03T19:56:50.717 回答
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
于 2011-02-08T08:25:48.547 回答
8

也许你想要的是

widget->setAttribute(Qt::WA_TransparentForMouseEvents)

? 这就是 QRubberBand 用来让它的父级处理鼠标事件的方法。至于键盘事件,QWidget 不会得到任何键盘事件,除非它为自己设置了一个 focusPolicy()。

setFocusPolicy( Qt::NoFocus );

因此应该处理键盘事件。

于 2009-07-10T11:27:22.503 回答
2

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

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

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

于 2009-06-19T17:20:50.047 回答
1

我认为覆盖应该起作用:

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

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

如果事件被识别,此函数返回 true,否则返回 false。如果已识别的事件被接受(参见 QEvent::accepted),则任何进一步的处理(例如到父窗口小部件的事件传播)都会停止。

于 2009-06-16T18:52:25.600 回答
1

使用 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);
}
于 2009-06-18T14:08:42.953 回答