web-dev-qa-db-ja.com

Qt-キーボードとマウスのイベントの透過性を備えたトップレベルのウィジェット?

アプリのメインウィンドウでマウスとキーボードのイベントを無視し、ウィンドウマネージャーのZオーダーでその下のアプリケーションに渡します。

childウィジェットがキーボードまたはマウスのイベントを無視するようにする方法はわかりますが、メインウィンドウはどうですか?

常に背景の真上に配置され、キーボードやマウスのイベントからは完全に見えないデスクトップウィジェットを作成しようとしています。 (パススルー)

Qt :: X11BypassWindowManagerHintはキーボードパススルーを取得します(残念ながらX11固有ですが、今のところ問題ありません)。では、マウスイベントはどうですか?

キーボードイベントを透過的にするOSに依存しない方法はありますか?

編集:

ここでのキーワードは透明性です。

マウスとキーボードのイベントを[〜#〜]食べる[〜#〜]したくないので、ウィンドウマネージャーに知らせてほしいそれらをまったく欲しくない。これらのイベントは、zorderで私の下にあるすべてのアプリケーションに送信する必要があります。

たとえば、ウィジェットで覆われているデスクトップアイコンをクリックして、ウィジェットがないかのように操作できるようにしたいです。

40
darron

私は次の解決策を見つけました(Linuxでテストされ、@ TheSHEEEPに従ってWindowsでも動作します):

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

最近のqtリリースで追加されました(いつ見つかりませんでした) http://doc.qt.io/qt-5/qt.html を参照してください。

11
mxttie

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
11
JProgrammer

多分あなたが欲しいのは

widget->setAttribute(Qt::WA_TransparentForMouseEvents)

?これは、QRubberBandが親にマウスイベントを処理させるために使用するものです。キーボードイベントに関しては、QWidgetはそれ自体にfocusPolicy()を設定しない限り、キーボードイベントを取得しません。

setFocusPolicy( Qt::NoFocus );

したがって、キーボードイベントを処理する必要があります。

8

ここで何かが足りないかもしれませんが、QMainWindowクラスをサブクラス化し、 QWidget :: event() メソッドをオーバーライドして常にfalseを返すようにしましたか?一部のイベントを処理する必要がある場合は、そのインテリジェンスをここに追加することもできます。

この手法により、アプリケーションに着信するイベントを検査し、必要に応じて、イベントフィルターを使用してそれらを食べることなく無視することができます。

これが機能しない場合は、 QCoreApplication :: notify() を呼び出し、 QApplication :: desktop)を呼び出して取得したデスクトップウィジェットにイベントを渡すことで、イベントをデスクトップにリダイレクトしようとすることができます。 () 。これでうまくいくかどうかはわかりませんが、試してみる価値があるようです。

2
Joe Corkery

オーバーライドは機能するはずだと思います。

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

これは、QWidgetクラスのドキュメントがevent()メンバー関数について述べていることの一部です。

この関数は、イベントが認識された場合はtrueを返し、それ以外の場合はfalseを返します。認識されたイベントが受け入れられた場合(QEvent :: acceptedを参照)、親ウィジェットへのイベント伝播などの処理は停止します。

1
Maleev

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);
}
1
Krsna