我有一个控件,其中包含QScrollArea中的几个QSpinBox对象。除非鼠标恰好位于QSpinBox之一上,否则在滚动区域中滚动时,所有方法都可以正常工作。然后,QSpinBox抢占焦点,并且转轮事件控制旋转框的值,而不是滚动滚动区域。
我不想完全禁用使用鼠标滚轮来操纵QSpinBox,但是我只希望在用户显式单击或单击QSpinBox时发生。有没有一种方法可以防止QSpinBox窃取QScrollArea的焦点?
如对以下答案的评论中所述,设置Qt::StrongFocus确实可以防止焦点rect出现在控件上,但是它仍然会窃取鼠标滚轮并调整旋转框中的值,并阻止QScrollArea滚动。与Qt::ClickFocus相同。
最佳答案
尝试从Spinbox的 Qt::WheelFocus
中删除 QWidget::focusPolicy
:
spin->setFocusPolicy( Qt::StrongFocus );
此外,您需要防止wheel事件到达Spinbox。您可以使用事件过滤器来做到这一点:
explicit Widget( QWidget * parent=0 )
: QWidget( parent )
{
// setup ...
Q_FOREACH( QSpinBox * sp, findChildren<QSpinBox*>() ) {
sp->installEventFilter( this );
sp->setFocusPolicy( Qt::StrongFocus );
}
}
/* reimp */ bool eventFilter( QObject * o, QEvent * e ) {
if ( e->type() == QEvent::Wheel &&
qobject_cast<QAbstractSpinBox*>( o ) )
{
e->ignore();
return true;
}
return QWidget::eventFilter( o, e );
}
格兰特·林伯格(Grant Limberg)编辑,以确保完整性,因为这使我90%地实现了目标:
除了以上mmutz所说的,我还需要做其他一些事情。我必须创建QSpinBox的子类并实现
focusInEvent(QFocusEvent*)
和focusOutEvent(QFocusEvent*)
。基本上,在focusInEvent
上,我将焦点策略更改为Qt::WheelFocus
,在focusOutEvent
上,将其更改回Qt::StrongFocus
。void MySpinBox::focusInEvent(QFocusEvent*)
{
setFocusPolicy(Qt::WheelFocus);
}
void MySpinBox::focusOutEvent(QFocusEvent*)
{
setFocusPolicy(Qt::StrongFocus);
}
此外,事件过滤器类中的eventFilter方法实现会根据spinbox子类的当前焦点策略更改其行为:
bool eventFilter(QObject *o, QEvent *e)
{
if(e->type() == QEvent::Wheel &&
qobject_cast<QAbstractSpinBox*>(o))
{
if(qobject_cast<QAbstractSpinBox*>(o)->focusPolicy() == Qt::WheelFocus)
{
e->accept();
return false;
}
else
{
e->ignore();
return true;
}
}
return QWidget::eventFilter(o, e);
}
关于c++ - QScrollArea内的QSpinBox : How to prevent Spin Box from stealing focus when scrolling?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5821802/