问题
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