64bit int Spin Box in QT

岁酱吖の 提交于 2020-01-02 03:30:31

问题


I'm building a windows program which shall have controls for 64bit numeric values. these controls shall be switchable to be signed or unsigned.

I found two controls: "Spin Box"(int32) and "Double Spin Box"(double) with double I'd be able to cover the range but it can't handle the precision.

Is there a way to change the data type of these controls?

Is it possible to create an own control which can handle signed and unsigned 64bit values? Is it possible to create a 128bit Spin box?

The only work around I can see right now is in using a string control and manually convert to an INT64 or UINT64 but I'm not very happy with this solution

Any other Ideas?

I'm on QT 4.7.4 and VS2010 with C++ thx


回答1:


You can derive QAbstractSpinBox and reimplement at least the virtual functions stepBy, stepEnabled and possibly validate() and fixup() for the input validation.




回答2:


I don't use fixup function. See code of my Сustom QSpinBox. class QLongLongSpinBox derived from QAbstractSpinBox

Don't forget call

setMaximum(std::numeric_limits<qlonglong>::max());
setMinimum(std::numeric_limits<qlonglong>::min());

after creating QLongLongSpinBox.

see qlonglongspinbox.h file:

#include <QtWidgets/QWidget>
#include <QtWidgets/QAbstractSpinBox>
#include <QtWidgets/QLineEdit>

class QLongLongSpinBoxPrivate;
class Q_WIDGETS_EXPORT QLongLongSpinBox : public QAbstractSpinBox
{
    Q_OBJECT

    Q_PROPERTY(qlonglong minimum READ minimum WRITE setMinimum)
    Q_PROPERTY(qlonglong maximum READ maximum WRITE setMaximum)

    Q_PROPERTY(qlonglong value READ value WRITE setValue NOTIFY valueChanged USER true)


    qlonglong m_minimum;
    qlonglong m_maximum;
    qlonglong m_value;

public:
    explicit QLongLongSpinBox(QWidget *parent = 0)
    {
        connect(lineEdit(), SIGNAL(textEdited(QString)), this, SLOT(onEditFinished()));
    };
    ~QLongLongSpinBox() {};

    qlonglong value() const
    {
        return m_value;
    };

    qlonglong minimum() const
    {
        return m_minimum;
    };

    void setMinimum(qlonglong min)
    {
        m_minimum = min;
    }

    qlonglong maximum() const
    {
        return m_maximum;
    };

    void setMaximum(qlonglong max)
    {
        m_maximum = max;
    }

    void setRange(qlonglong min, qlonglong max)
    {
        setMinimum(min);
        setMaximum(max);
    }

    virtual void stepBy(int steps)
    {
        auto new_value = m_value;
        if (steps < 0 && new_value + steps > new_value) {
            new_value = std::numeric_limits<qlonglong>::min();
        }
        else if (steps > 0 && new_value + steps < new_value) {
            new_value = std::numeric_limits<qlonglong>::max();
        }
        else {
            new_value += steps;
        }

        lineEdit()->setText(textFromValue(new_value));
        setValue(new_value);
    }

protected:
    //bool event(QEvent *event);
    virtual QValidator::State validate(QString &input, int &pos) const
    {
        bool ok;
        qlonglong val = input.toLongLong(&ok);
        if (!ok)
            return QValidator::Invalid;

        if (val < m_minimum || val > m_maximum)
            return QValidator::Invalid;

        return QValidator::Acceptable;
    }

    virtual qlonglong valueFromText(const QString &text) const
    {
        return text.toLongLong();
    }

    virtual QString textFromValue(qlonglong val) const
    {
        return QString::number(val);
    }
    //virtual void fixup(QString &str) const;

    virtual QAbstractSpinBox::StepEnabled stepEnabled() const
    {
        return StepUpEnabled | StepDownEnabled;
    }


public Q_SLOTS:
    void setValue(qlonglong val)
    {
        if (m_value != val) {
            lineEdit()->setText(textFromValue(val));
            m_value = val;
        }
    }

    void onEditFinished()
    {
        QString input = lineEdit()->text();
        int pos = 0;
        if (QValidator::Acceptable == validate(input, pos))
            setValue(valueFromText(input));
        else
            lineEdit()->setText(textFromValue(m_value));
    }

Q_SIGNALS:
    void valueChanged(qlonglong v);

private:
    Q_DISABLE_COPY(QLongLongSpinBox)

    Q_DECLARE_PRIVATE(QLongLongSpinBox)
};



回答3:


To use you custom class (Widget) it in Qt Creator:

  • create QWidget widget
  • List item
  • select Promote to.. in widget menu New Promoted Class: QWigdet
    Promoted class name QLongLongSpinBox
    Header file: write qlonglongspinbox.h
    Promote
  • select Promote to QLongLongSpinBox
  • save

You can see

<item>
    <widget class="QLongLongSpinBox" name="value_integer" native="true"/>
</item>

and:

<customwidgets>
  <customwidget>
   <class>QLongLongSpinBox</class>
   <extends>QWidget</extends>
   <header>qlonglongspinbox.h</header>
   <container>1</container>
  </customwidget>
</customwidgets>

in *.ui file

in ui_*.h generating file you see you class:

#include "qlonglongspinbox.h"
QLongLongSpinBox *object_name;
value_integer = new QLongLongSpinBox(YourWidgetName);
value_integer->setObjectName(QStringLiteral("value_integer"));
verticalLayout->addWidget(value_integer);


来源:https://stackoverflow.com/questions/8383620/64bit-int-spin-box-in-qt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!