4

Qt ダイアログを従来の Win32 アプリケーションに統合しましたが、Qt->Win32 から伝播するキーボード イベントを管理する方法に少し困惑しています。Qt がイベント (編集ボックスへの入力など) を「処理」しているかどうかをテストし、これらのイベントがホスト アプリケーションに伝播するのを防ぐ方法はありますか?

Win32 アプリケーションには独自の非常に複雑なアクセラレータ システムがあり、ネイティブの編集ボックスを操作する場合、通常、アクセラレータを手動で無効にします。Qtダイアログは複数のアプリケーション間で共有されるウィジェットであるため、これを行うことはできません。

現在、ダイアログ全体でホスト アクセラレータを無効にしてフォーカスを得ていますが、編集ボックスからの kbd イベントの伝播を防ぐように Qt に指示することは可能でしょうか? 理想的には、QtDialogs コードを変更せずに (ただし、必要に応じて変更できますか?)

4

2 に答える 2

3

これが実際に機能するかどうかはわかりませんが、これを試してみてください:

class KeyEventPropagetionPreventer: public QObject
{
public:
    KeyEventPropagetionPreventer( QWidget * widget ) 
    : QObject( widget ), widget( widget ), instercept_events( true )
    {
        widget->installEventFilter( this )
    }

    bool eventFilter(QObject *obj, QEvent *event)
    {
        if ( intercept_events && event->type() == QEvent::KeyPress) // or other types if needed
        {
            intercept_events = false; // prevents eating your own events
            QKeyEvent new_event( *event ); // Might be that you need to implement your own copying function if the copyconstructor is disabled
            QApplication::sendEvent(this->widget, &new_event);
            instercept_events = true;
            return true;
        } 
        else 
        {
            return QObject::eventFilter(obj, event);
        }
    }

private:
    QWidget * widget;
    bool instercept_events;
}

次に、ダイアログを作成する場所に次の行を追加します。

new KeyEventPropagetionPreventer( your_qt_dialog ); // will be deleted by the Qt parent/child system when the dialog is deleted.

アイデアは、すべてのキーボード イベントをインターセプトすることですが、そのコピーを作成してウィジェットに送信することもできます。インターセプトが実際にイベントの伝播を防ぎ (qt-eventsystem-only などではない)、QApplication::sendEvent() 自体が伝播しないことを願っています。

これがうまくいくことを願っています、頑張ってください!

(ps。このコードはテストまたはコンパイルされていません)

于 2015-12-20T18:27:27.130 に答える
1

Qtがイベントを「処理」しているかどうかをテストする方法はありますか(たとえば、編集ボックスへの入力)

まだ使用していない場合に備えて、すべてのメッセージを追跡できるSpy++ (Visual Studio に含まれています) を確認してください。

私は Qt に詳しくありませんが、Win32 ですべてのメッセージをキャッチしたい場合は、次GetMessage()のように使用できます。

BOOL bRet;

while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{ 
    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else  // you could do whatever you want with the message before it is dispatched
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
}
于 2015-12-25T03:04:49.830 に答える