当输入高于最大值的值时,如何将QSpinBox的值设置为max?

时间:2018-01-27 22:39:03

标签: c++ qt

Qt的SpinBox小部件的默认行为对我的应用程序来说是非常不受欢迎的。如果最大值为998,并且用户尝试键入" 999",则SpinBox将获得99的值,这与用户想要的值相差很远。

是否有选项或备用窗口小部件在这种情况下会获取值998?

编辑:好的,我已经开始通过子类化方法开展工作,但它并没有按预期工作。

标题文件:

// myspinbox.h

#ifndef MYSPINBOX_H
#define MYSPINBOX_H


#include <QSpinBox>
#include <QValidator>

class MySpinBox : public QSpinBox
{
    Q_OBJECT

public:
    explicit MySpinBox(QWidget *parent = Q_NULLPTR);

   // QValidator::State validate(QString &text, int &pos) const override;

    void fixup(QString &input) const override;
};

#endif // MYSPINBOX_H

源文件:

// myspinbox.cpp

#include <QtWidgets>
#include <iostream>
#include "myspinbox.h"

MySpinBox::MySpinBox(QWidget *parent) : QSpinBox(parent) {}

//QValidator::State MySpinBox::validate(QString &text, int &pos) const {
//    return QValidator::Acceptable;
//}

void MySpinBox::fixup(QString &input) const {
    std::cout << "fixup called on input: " << input.toStdString() << std::endl;
    int int_val = input.toInt();
    int max_val = this->maximum();
    if (int_val > max_val) {
        input = QString::number(max_val);
        std::cout << "Max val is " << max_val << std::endl;
    }
}

永远不会显示消息fixup called on input...

QSpinBox源代码中,有一个函数 {10}到第1045行到第1050行中的QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, QValidator::State &state) const正在调整输入值,如果它不在允许的范围内。我不确定覆盖fixup的给定建议是否有效。

1 个答案:

答案 0 :(得分:2)

子类QSpinBox,而不是覆盖这两种方法:

  1. QValidator::State QSpinBox::validate(QString &text, int &pos) const
  2. void QAbstractSpinBox::fixup(QString &input) const
  3. 请注意,您不希望用户在文本编辑中输入可以输入的强约束,因此请仔细测试并思考用户在不同情况下的感受。

    以下是使用C ++ 11的代码示例:

    class AltSpinBox : public QSpinBox
    {
        Q_OBJECT
    public:
        using QSpinBox::QSpinBox;
    
    protected:
        void fixup(QString &input) const;
        QValidator::State validate(QString &text, int &pos) const;
    };
    
    void AltSpinBox::fixup(QString &input) const
    {
        auto isOk = false;
        auto value = input.toInt(&isOk, displayIntegerBase());
        if (isOk) {
            value = qBound(minimum(), value, maximum());
            input = QString::number(value, displayIntegerBase());
        } else {
            QSpinBox::fixup(input);
        }
    }
    
    QValidator::State AltSpinBox::validate(QString &text, int &pos) const
    {
        auto isOk = false;
        auto value = text.toInt(&isOk, displayIntegerBase());
        if (isOk) {
            if (value >= minimum() && value <= maximum())
                return QValidator::Acceptable;
            return QValidator::Intermediate;
        } else {
            return QSpinBox::validate(text, pos);
        }
    }
    

    我测试了它,它的工作方式应该如此。可能你想稍微调整一下。