2014-09-25 47 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上重新安裝事件過濾器。