1

ウィジェット内のどこかにマウスをドラッグして、マウスでスクロールバー (コンテンツ) をスクロールできる拡張「QScrollArea」ウィジェットを実装したいと考えています。この目的のために、フォーカスが誤って一部の子に移動しないように、子ウィジェットを無視したいと考えています。

WA_TransparentForMouseEvents私の解決策 (これは機能していません) は、すべてのマウス イベントが my の viewportEvent() メソッドに送られるようにコンテンツ ウィジェット属性を設定することQScrollAreaExです。ここでは、マウス メッセージを処理します。たとえば、意図がスクロールバーの位置をドラッグすることなのか、子ウィジェットの一部と対話すること (アクティブ化、選択、キャレットの移動など) なのかを判断できます。

私の最初の試みは、メッセージMouseButtonPressおよびMouseButtonReleaseイベントを、設定されていない場合にフォーカスされていた下の子ウィジェット (widget()->childAt(e->pos())) のみにリダイレクトすることでしWA_TransparentForMouseEventsた。しかし、それはうまくいきませんでした。ウィジェットのどれもフォーカスを受け取りませんでした。しかし、なぜ?

bool viewportEvent(QEvent* e) {
    bool IsMouseEvent = e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseMove;
    QMouseEvent* me = (QMouseEvent*) e;

    bool IsHandled = false;

    if (IsMouseEvent) {
        if (e->type() == QEvent::MouseButtonPress) {
            _PressEvent = *me;
            IsHandled = true; // Eating press event
        } else if (e->type() == QEvent::MouseButtonRelease) {
            QPoint PressPoint = _PressEvent.pos();
            widget()->setAttribute(Qt::WA_TransparentForMouseEvents, false);
            QWidget* w = widget()->childAt(PressPoint);
            if (w) {
                QPoint p1 = w->mapFrom(widget(), _PressEvent.pos());
                QPoint p2 = w->mapFrom(widget(), me->pos());
                QMouseEvent* e1 = new QMouseEvent(QEvent::MouseButtonPress, p1, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
                QMouseEvent* e2 = new QMouseEvent(QEvent::MouseButtonRelease, p2, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
                QCoreApplication::postEvent(w, e1);
                QCoreApplication::postEvent(w, e2);
            }
            widget()->setAttribute(Qt::WA_TransparentForMouseEvents, true);
        }
    }
    if (IsHandled) return true;
    return QScrollArea::viewportEvent(e);
}

2番目のテストは次のとおりです。

bool viewportEvent(QEvent* e) {
    bool IsMouseEvent = e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseMove;
    QMouseEvent* me = (QMouseEvent*) e;

    bool IsHandled = false;

    if (IsMouseEvent) {
        if (e->type() == QEvent::MouseButtonPress) {
            _PressEvent = *me;
            IsHandled = true; // Eating press event
        } else if (e->type() == QEvent::MouseButtonRelease) {
            QPoint PressPoint = _PressEvent.pos();
            widget()->setAttribute(Qt::WA_TransparentForMouseEvents, false);
            QWidget* w = widget()->childAt(PressPoint);
            if (w && w != widget()) {
                QCoreApplication::sendEvent(widget(), &_PressEvent);
                QCoreApplication::sendEvent(widget(), e);
            }
            widget()->setAttribute(Qt::WA_TransparentForMouseEvents, true);
        }
    }
    if (IsHandled) return true;
    return QScrollArea::viewportEvent(e);
}

それらのどれも機能していませんでした。リダイレクトが機能しないのはなぜですか。私の目的のためのより良い解決策はありますか?

4

0 に答える 0