0

Qt 5.3.2with Qt Creator 3.2.1with MinGW 4.8.2onを使用していWindows 7ます。がありQSpinBox、マウスが の上にある場合にのみ、マウス ホイールでその値を変更できますQSpinBox。マウスが の上にない場合、にまだフォーカスがQSpinBoxあっても、マウス ホイールをスクロールしても効果がありません。マウスがホバリングしていなくても、マウス ホイールでフォーカスQSpinBoxされている の値を変更できるようにするには、どうすればよいですか? QSpinBoxに設定mouseTrackingtrueても、その効果はありません。

4

2 に答える 2

4

これを行うために使用eventFilterします。あなたにインストールしますmainWindow

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
        if (obj == this && event->type() == QEvent::Wheel)
        {
            QWheelEvent *wheelEvent = static_cast<QWheelEvent *>(event);
            if(wheelEvent->delta() > 0)
                ui->spinBox->setValue(ui->spinBox->value() + 1);
            else
                ui->spinBox->setValue(ui->spinBox->value() - 1);
        }
}

あくまで一例ですので、お好みで改良してください。

またはこれを使用します:

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

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

この例では、wheel イベントを検出すると、それをスピンボックスに送信します。

でも忘れないで

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

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

DmitrySazonov推奨どおり。spinBox がフォーカスされている場合は wheelEvents を検出し、spinBox がフォーカスを失った場合はホイールに反応しません (他のウィジェットは正常に反応します)。これを 1 つの eventFilter で行います。これを行うには、新しい bool 変数を提供します。例えば:

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);
}
于 2014-09-25T14:55:08.963 に答える
1

質問では言及しませんでしたが、複数QSpinBoxあり、それらすべてをテストするのは最適ではないように思われるため、汎用メッセージフォワーダーが必要です。チェルノブイリのコードに基づいて、独自のバージョンのメッセージ フィルターを作成しました。

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これにより、すべてのQWidgetがフォーカスのある に転送されます。転送する必要がある他のイベントを追加することもできます。

イベント フィルター内のqApp->removeEventFilterandqApp->installEventFilterは、スタック オーバーフローを引き起こすメイン ウィンドウをスクロールするときにイベント フィルターがそれ自体を呼び出すのを防ぐ唯一の方法です (状態focusWidget != thisは役に立ちません)。おそらく、すべての にイベント フィルタを再インストールせずに、無限再帰を防ぐ方法がありますQWheelEvent

于 2014-09-26T11:45:15.617 に答える