2014-09-25 379 views
0

我使用Qt 5.3.2Qt Creator 3.2.1MinGW 4.8.2Windows 7上。我有一个QSpinBox,只有鼠标超过QSpinBox,才能使用鼠标滚轮更改其值。如果鼠标没有超过QSpinBox,滚动鼠标滚轮不起作用,即使QSpinBox仍然有焦点。我需要做什么才能够更改QSpinBox中的值,即使鼠标没有悬停在鼠标滚轮上,鼠标滚轮的焦点也是如此。将​​设置为true没有这种效果。使QSpinBox对光标未滚动时鼠标滚轮事件作出反应

+0

请参阅我的编辑,我添加了代码,它可以满足您的需求,但不需要额外的布尔变量。 – Chernobyl 2014-09-25 16:45:20

回答

4

使用eventFilter来做到这一点。您mainWindow安装:

这仅仅是例子,这样你就可以改善它,只要你想。

或者使用:

bool MainWindow::eventFilter(QObject *obj, QEvent *event) 
{ 

     if (obj == this && event->type() == QEvent::Wheel) 
     { 
      QApplication::sendEvent(ui->spinBox,event); 
     } 
} 

在这个例子中,当你发现滚轮事件,你把它发送给你的纺纱器。

但不要忘了

protected: 
bool eventFilter(QObject *obj, QEvent *event);//in header 

qApp->installEventFilter(this);//in constructor 

由于DmitrySazonov建议。当我们的spinBox处于焦点时,我们将检测wheelEvents,当spinBox失去焦点时,我们不会对车轮作出反应(其他小部件反应正常)。我们在一个事件过滤器中执行此操作。为此提供新的布尔变量。例如:

private: 
bool spin;//in header 

在构造函数初始化:

spin = false; 

和你eventFilter应该的。

bool MainWindow::eventFilter(QObject *obj, QEvent *event) 
    { 
     if(obj == ui->spinBox && event->type() == QEvent::FocusIn) 
      spin = true; 


     if(spin) 
     { 
      if (obj == this && event->type() == QEvent::Wheel) 
      { 
       QApplication::sendEvent(ui->spinBox,event); 
      } 
     } 

     if(obj == ui->spinBox && event->type() == QEvent::FocusOut) 
      spin = false; 
    } 

或者只做这一点,无需额外的变量:

if (obj == this && event->type() == QEvent::Wheel) 
{ 
    if(ui->spinBox->hasFocus()) 
     QApplication::sendEvent(ui->spinBox,event); 
} 
+0

如果仅当控件获得焦点时才安装事件过滤器,则可以改进您的解决方案。并且在焦点上卸载事件过滤器丢失。 – 2014-09-25 15:47:23

+0

@DmitrySazonov对不起,但这是什么控制?你的意思是在'QWidget :: focusInEvent'中安装过滤器,并在'QWidget :: focusOutEvent'中删除它?感谢您的关注。 – Chernobyl 2014-09-25 16:01:41

+0

是的,在旋梭上处理焦点事件。 – 2014-09-25 16:06:08

1

我没有提到它的问题,但我有一个以上的QSpinBox和测试所有这些似乎次优的,所以我需要一个通用的消息转发器。基于该Chernobyl's code我做我自己的邮件过滤器的版本:

bool MainWindow::eventFilter(QObject *obj, QEvent *event){ 
    if (obj == this && event->type() == QEvent::Wheel) 
    { 
     auto focusWidget = QApplication::focusWidget(); 
     if (focusWidget){ 
      qApp->removeEventFilter(this); 
      QApplication::sendEvent(focusWidget, event); 
      qApp->installEventFilter(this); 
      return true; 
     } 
    } 
    return false; 
} 

此选项把所有QWheelEvent S到QWidget与焦点。也可以添加需要转发的其他事件。

qApp->removeEventFilterqApp->installEventFilter事件过滤器里面我发现,阻止事件过滤器的主窗口中滚动导致堆栈溢出(条件focusWidget != this没有帮助)时自称的唯一途径。可能有一种方法可以防止无限递归,而无需在每个QWheelEvent上重新安装事件过滤器。