ウィジェット内のどこかにマウスをドラッグして、マウスでスクロールバー (コンテンツ) をスクロールできる拡張「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);
}
それらのどれも機能していませんでした。リダイレクトが機能しないのはなぜですか。私の目的のためのより良い解決策はありますか?