From da78b3861569479c2c67f1264c0da38cc351e752 Mon Sep 17 00:00:00 2001 From: yeshanshan Date: Fri, 14 Aug 2026 17:31:22 +0800 Subject: [PATCH] fix: wheel event not propagating to parent in Qt6 Qt6 QApplication::notify pre-accepts wheel events (we.setAccepted(true)) before delivery. If a widget's wheelEvent doesn't call the parent class (which would ignore() the event), the event stays accepted and does not propagate to parent widgets (e.g. QScrollArea). This differs from Qt5 where unhandled wheel events propagated by default. Fix by overriding wheelEvent in DSpinBox, DDoubleSpinBox, DComboBox following the pattern from commit fe16c8e9 (settings/ComboBox): - hasFocus(): call base class wheelEvent (stepBy + accept, default behavior) - no focus: call QWidget::wheelEvent (ignore() -> event propagates) For DSlider, which is a QWidget containing an inner QSlider with an eventFilter on qApp, fix the eventFilter instead: when the inner slider has no focus, call e->ignore() before returning true so the event propagates to the parent scrollarea in Qt6. This fixes the Qt6-specific regression where scrolling over spinbox / combobox / slider inside a scrollarea was blocked. Ref: DDE-72 --- include/widgets/dcombobox.h | 2 ++ include/widgets/dslider.h | 2 +- include/widgets/dspinbox.h | 10 +++++++++- src/widgets/dcombobox.cpp | 12 ++++++++++++ src/widgets/dslider.cpp | 8 ++++++-- src/widgets/dspinbox.cpp | 24 +++++++++++++++++++++++- 6 files changed, 53 insertions(+), 5 deletions(-) diff --git a/include/widgets/dcombobox.h b/include/widgets/dcombobox.h index 62b94cf11..34c53d56a 100644 --- a/include/widgets/dcombobox.h +++ b/include/widgets/dcombobox.h @@ -23,6 +23,8 @@ class LIBDTKWIDGETSHARED_EXPORT DComboBox : public QComboBox, public DCORE_NAMES protected: DComboBox(DComboBoxPrivate &dd, QWidget *parent); + void wheelEvent(QWheelEvent *event) override; + // QComboBox interface public: virtual void showPopup() override; diff --git a/include/widgets/dslider.h b/include/widgets/dslider.h index b08414769..812a16f1b 100644 --- a/include/widgets/dslider.h +++ b/include/widgets/dslider.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2011 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later diff --git a/include/widgets/dspinbox.h b/include/widgets/dspinbox.h index 8a14cbf1d..eb9a6d3cb 100644 --- a/include/widgets/dspinbox.h +++ b/include/widgets/dspinbox.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2015 - 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2015 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -25,6 +25,10 @@ class LIBDTKWIDGETSHARED_EXPORT DSpinBox : public QSpinBox, public DTK_CORE_NAME public: explicit DSpinBox(QWidget *parent = nullptr); +protected: + void wheelEvent(QWheelEvent *event) override; + +public: QLineEdit *lineEdit() const; bool isAlert() const; @@ -65,6 +69,10 @@ class LIBDTKWIDGETSHARED_EXPORT DDoubleSpinBox : public QDoubleSpinBox, public D public: explicit DDoubleSpinBox(QWidget *parent = nullptr); +protected: + void wheelEvent(QWheelEvent *event) override; + +public: bool isAlert() const; void showAlertMessage(const QString &text, int duration = 3000); void showAlertMessage(const QString &text, QWidget *follower, int duration = 3000); diff --git a/src/widgets/dcombobox.cpp b/src/widgets/dcombobox.cpp index 6867fe1ce..bd528aae6 100644 --- a/src/widgets/dcombobox.cpp +++ b/src/widgets/dcombobox.cpp @@ -32,6 +32,7 @@ #include #include #include +#include DWIDGET_BEGIN_NAMESPACE @@ -109,6 +110,7 @@ DComboBox::DComboBox(QWidget *parent) { D_D(DComboBox); d->init(); + setFocusPolicy(Qt::StrongFocus); } DComboBox::DComboBox(DComboBoxPrivate &dd, QWidget *parent) @@ -117,6 +119,16 @@ DComboBox::DComboBox(DComboBoxPrivate &dd, QWidget *parent) { D_D(DComboBox); d->init(); + setFocusPolicy(Qt::StrongFocus); +} + +void DComboBox::wheelEvent(QWheelEvent *event) +{ + if (hasFocus()) { + QComboBox::wheelEvent(event); + } else { + QWidget::wheelEvent(event); + } } /*! diff --git a/src/widgets/dslider.cpp b/src/widgets/dslider.cpp index e10673ce2..45a2929a0 100644 --- a/src/widgets/dslider.cpp +++ b/src/widgets/dslider.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2011 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -136,7 +136,11 @@ bool DSlider::eventFilter(QObject *watched, QEvent *e) Q_D(DSlider); if ((watched == d->slider) && (e->type() == QEvent::Wheel)) { - return !d->mouseWheelEnabled; + if (d->mouseWheelEnabled && d->slider->hasFocus()) { + return false; // let QSlider::wheelEvent handle it (stepBy + accept) + } + e->ignore(); // Qt6: un-accept so event propagates to parent (e.g. scrollarea) + return true; // block delivery to the inner QSlider } if (e->type() == QEvent::MouseButtonRelease) { diff --git a/src/widgets/dspinbox.cpp b/src/widgets/dspinbox.cpp index 08543636b..e03343615 100644 --- a/src/widgets/dspinbox.cpp +++ b/src/widgets/dspinbox.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2015 - 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2015 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -8,6 +8,8 @@ #include "private/dspinbox_p.h" #include "dlineedit.h" +#include + DWIDGET_BEGIN_NAMESPACE DSpinBoxPrivate::DSpinBoxPrivate(DSpinBox *parent) : @@ -63,6 +65,16 @@ DSpinBox::DSpinBox(QWidget *parent) : DObject(*new DSpinBoxPrivate(this)) { d_func()->init(); + setFocusPolicy(Qt::StrongFocus); +} + +void DSpinBox::wheelEvent(QWheelEvent *event) +{ + if (hasFocus()) { + QSpinBox::wheelEvent(event); + } else { + QWidget::wheelEvent(event); + } } /*! @@ -180,6 +192,16 @@ DDoubleSpinBox::DDoubleSpinBox(QWidget *parent) : DObject(*new DDoubleSpinBoxPrivate(this)) { d_func()->init(); + setFocusPolicy(Qt::StrongFocus); +} + +void DDoubleSpinBox::wheelEvent(QWheelEvent *event) +{ + if (hasFocus()) { + QDoubleSpinBox::wheelEvent(event); + } else { + QWidget::wheelEvent(event); + } } bool DDoubleSpinBox::isAlert() const