QScrollArea 内的 QSpinBox:如何防止 Spin Box 在滚动时窃取焦点?
我有一个在 QScrollArea 内有几个 QSpinBox 对象的控件。在滚动区域中滚动时一切正常,除非鼠标恰好位于 QSpinBox 之一上。然后 QSpinBox 窃取焦点,滚轮事件操纵旋转框值而不是滚动滚动区域。
我不想完全禁用使用鼠标滚轮来操作 QSpinBox,但我只希望用户明确单击或按 Tab 键进入 QSpinBox 时才会发生这种情况。有没有办法防止 QSpinBox 窃取 QScrollArea 的焦点?
正如下面对答案的评论中所述,设置 Qt::StrongFocus 确实会阻止焦点矩形出现在控件上,但它仍然会窃取鼠标滚轮并调整旋转框中的值并阻止 QScrollArea 滚动。与 Qt::ClickFocus 相同。
I have a control with several QSpinBox objects inside a QScrollArea. All works fine when scrolling in the scroll area unless the mouse happens to be over one of the QSpinBoxes. Then the QSpinBox steals focus and the wheel events manipulate the spin box value rather than scrolling the scroll area.
I don't want to completely disable using the mouse wheel to manipulate the QSpinBox, but I only want it to happen if the user explicitly clicks or tabs into the QSpinBox. Is there a way to prevent the QSpinBox from stealing the focus from the QScrollArea?
As said in a comment to an answer below, setting Qt::StrongFocus does prevent the focus rect from appearing on the control, however it still steals the mouse wheel and adjusts the value in the spin box and stops the QScrollArea from scrolling. Same with Qt::ClickFocus.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
为了解决这个问题,我们需要注意以下两件事:
Qt::StrongFocus
来完成。QSpinBox
子类中重新实现QWidget::wheelEvent
来完成。实现此功能的
MySpinBox
类的完整代码:就是这样。请注意,如果您不想创建新的
QSpinBox
子类,那么您也可以使用事件过滤器来解决此问题。In order to solve this, we need to care about the two following things:
Qt::StrongFocus
.QWidget::wheelEvent
within aQSpinBox
subclass.Complete code for a
MySpinBox
class which implements this:That's it. Note that if you don't want to create a new
QSpinBox
subclass, then you can also use event filters instead to solve this.尝试删除
Qt::WheelFocus
来自旋转框'QWidget::focusPolicy
:此外,您需要防止滚轮事件到达旋转框。您可以使用事件过滤器来做到这一点:
为了完整性,从 Grant Limberg 进行编辑,因为这让我完成了 90% 的工作:
除了上面 mmutz 所说的之外,我还需要做一些其他事情。我必须创建 QSpinBox 的子类并实现 focusInEvent(QFocusEvent*) 和 focusOutEvent(QFocusEvent*)。基本上,在
focusInEvent
上,我将焦点策略更改为Qt::WheelFocus
,在focusOutEvent
上,我将其更改回Qt ::强焦点
。此外,事件过滤器类中的 eventFilter 方法实现会根据 spinbox 子类的当前焦点策略更改其行为:
Try removing
Qt::WheelFocus
from the spinbox'QWidget::focusPolicy
:In addition, you need to prevent the wheel event from reaching the spinboxes. You can do that with an event filter:
edit from Grant Limberg for completeness as this got me 90% of the way there:
In addition to what mmutz said above, I needed to do a few other things. I had to create a subclass of QSpinBox and implement
focusInEvent(QFocusEvent*)
andfocusOutEvent(QFocusEvent*)
. Basically, on afocusInEvent
, I change the Focus Policy toQt::WheelFocus
and on thefocusOutEvent
I change it back toQt::StrongFocus
.Additionally, the eventFilter method implementation in the event filter class changes its behavior based on the current focus policy of the spinbox subclass:
我尝试解决方案。易于使用,无需子类化。
首先,我创建了一个新的帮助器类:
然后我在运行时或在 Qt Designer 中将有问题的小部件的焦点策略设置为
StrongFocus
。然后我安装我的事件过滤器:
ui.comboBox->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui.comboBox));
完成。当父对象(组合框)被销毁时,
MouseWheelWidgetAdjustmentGuard
将自动删除。My attempt at a solution. Easy to use, no subclassing required.
First, I created a new helper class:
Then I set the focus policy of the problematic widget to
StrongFocus
, either at runtime or in Qt Designer.And then I install my event filter:
ui.comboBox->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui.comboBox));
Done. The
MouseWheelWidgetAdjustmentGuard
will be deleted automatically when the parent object - the combobox - is destroyed.只是为了扩展,您可以使用 eventFilter 来执行此操作,而不需要派生新的 QMySpinBox 类型类:
Just to expand you can do this with the eventFilter instead to remove the need to derive a new QMySpinBox type class:
这是我的 Violet Giraffe 的 Python PyQt5 端口答案:
This is my Python PyQt5 port of Violet Giraffe answer:
在这篇文章的帮助下,我们为 Python/PySide 制定了一个解决方案。如果有人偶然发现这个。就像我们一样:]
With help from this post we cooked a solution for Python/PySide. If someone stumbles across this. Like we did :]
只是为了帮助有需要的人,它缺少一个小细节:
Just to help anyone's in need, it lacks a small detail: