似乎Qt默认将输入数字的精度设置为2位小数。如果小数=2,用户输入例如4的数字,则向用户显示4.00。是否可以仅显示4但允许用户编辑它并且相应更新值的选项?
#include <QtWidgets>
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QDoubleSpinBox qEdit;
qEdit.show();
// install signal handler
QObject::connect(&qEdit,
(void (QDoubleSpinBox::*)(double))&QDoubleSpinBox::valueChanged,
[&](double value){ qDebug() << "qEdit.value:" << qEdit.value(); });
// run application
return app.exec();
}
QDoubleSpinBox
的行为可以通过创建派生类 DoubleSpinBox
并重载相应方法来更改。virtual QValidator::State validate(QString &text, int &pos) const override
。QDoubleSpinBox
的 源代码:QValidator::State QDoubleSpinBox::validate(QString &text, int &pos) const
{
Q_D(const QDoubleSpinBox);
QValidator::State state;
d->validateAndInterpret(text, pos, state);
return state;
}
因此,实际工作是由QDoubleSpinBoxPrivate :: validateAndInterpret()
完成的,该函数(在撰写本文时)有148行代码 - 非常复杂。
为了提供概念证明,我决定将其缩短并使其不那么完美:
QValidator::State DoubleSpinBox::validate(QString &text, int&) const
{
bool ok = false;
locale().toDouble(text, &ok);
return ok ? QValidator::Acceptable : QValidator::Invalid;
}
4.1234
。在输入时,输出为:4
4.1
4.12
0
virtual double valueFromText(const QString &text) const
。double DoubleSpinBox::valueFromText(const QString &text) const
{
bool ok = false;
double value = locale().toDouble(text, &ok);
return ok ? value : QDoubleSpinBox::value();
}
4.1234
现在被接受并存储。输出为:4
4.1
4.12
4.123
4.1234
5.12
。然而,内部值仍具有完整的精度,如输出所示:5.1234
完整的示例代码testQDoubleSpinBox.cc
:
#include <QtWidgets>
// a class for a customized QDoubleSpinBox
class DoubleSpinBox: public QDoubleSpinBox {
public:
// constructor.
explicit DoubleSpinBox(QWidget *pQParent = nullptr):
QDoubleSpinBox(pQParent)
{ }
// destructor.
virtual ~DoubleSpinBox() = default;
// disabled:
DoubleSpinBox(const DoubleSpinBox&) = delete;
DoubleSpinBox& operator=(const DoubleSpinBox&) = delete;
public:
/* converts value from text.
*
* Overloaded to process accepted input correctly.
*/
virtual double valueFromText(const QString &text) const override;
protected:
/* determines whether input is valid.
*
* Overloaded to change accepted input.
*/
virtual QValidator::State validate(QString &text, int &pos) const override;
};
QValidator::State DoubleSpinBox::validate(QString &text, int&) const
{
bool ok = false;
locale().toDouble(text, &ok);
return ok ? QValidator::Acceptable : QValidator::Invalid;
}
double DoubleSpinBox::valueFromText(const QString &text) const
{
bool ok = false;
double value = locale().toDouble(text, &ok);
return ok ? value : QDoubleSpinBox::value();
}
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
DoubleSpinBox qEdit;
qEdit.show();
// install signal handlers
QObject::connect(&qEdit,
(void (QDoubleSpinBox::*)(double))&QDoubleSpinBox::valueChanged,
[&](double){ qDebug() << "qEdit.value:" << qEdit.value(); });
// run application
return app.exec();
}
Qt项目文件 testQDoubleSpinBox.pro
:
SOURCES = testQDoubleSpinBox.cc
QT += widgets
在 Windows 10 上使用 cygwin 的示例会话:
$ qmake-qt5 testQDoubleSpinBox.pro
$ make
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQDoubleSpinBox.o testQDoubleSpinBox.cc
g++ -o testQDoubleSpinBox.exe testQDoubleSpinBox.o -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
$ ./testQDoubleSpinBox
Qt Version: 5.9.2
qEdit.value: 4
qEdit.value: 4.1
qEdit.value: 4.12
qEdit.value: 4.123
qEdit.value: 4.1234
qEdit.value: 5.1234
是的,你可以。不过你需要重新实现QDoubleSpinBox
。
通过创建一个自定义类,并继承该spinbox,你可以重写QDoubleSpinBox::textFromValue
方法。正如其名称所示,此方法用于将double类型转换为字符串表示形式。
可能的实现方式:
QString MyDoubleSpinBox::textFromValue(double value) const
{
return QLocale().toString(value, 'g', QLocale::FloatingPointShortest);
}