QSpinBox / QDoubleSpinBox默认为十进制值。是否可以将十进制更改为角度?
UPDATE>请看图片。这是我想在QSpinBox / QDoubleSpinBox中获得的效果。
答案 0 :(得分:1)
首先 - 使用单个旋转框来操纵这样的值是不适用的,因为它代表了一个重要的范围。从用户体验的角度来看,每个组件的专用旋转框都会更容易。
第二 - 如果你仍然坚持使用单个旋转框,Qt没有一个可以开箱即用的小部件。但是,您可以轻松扩展QDoubleSpinBox
并重载textFromValue()
方法,该方法决定了旋转框显示的文本,然后您可以根据您拥有的任何原始数据组合字符串值。代表地点。
答案 1 :(得分:0)
是的,这是可能的。只需覆盖valueFromText
,textFromValue
和validate
(可选fixup
)。
textFromValue
应该很容易valueFromText
和validate
需要解析功能,因此请为其提取常用方法。fixup
仅在您知道如何纠正用户错误以及在某些情况下validate
何时返回QValidator::Intermediate时使用。请参阅documentation。
这是我的解决方案C ++ 11:
#ifndef DEGREESPINBOX_H
#define DEGREESPINBOX_H
#include <QDoubleSpinBox>
class DegreeSpinBox : public QDoubleSpinBox
{
Q_OBJECT
public:
using QDoubleSpinBox::QDoubleSpinBox;
QString textFromValue(double value) const override;
double valueFromText(const QString &text) const override;
QValidator::State validate(QString &text, int &pos) const override;
private:
static void extractDegMinSecFrom(double value,
int *degrees,
int *minutes,
double *seconds);
static bool parse(QString str, double *result);
static bool areSeparatorsValid(QChar deg, QChar min, QChar sec);
};
#endif // DEGREESPINBOX_H
cpp文件
#include "degreespinbox.h"
#include <QTextStream>
#include <cmath>
QString DegreeSpinBox::textFromValue(double value) const {
int degrees, minutes;
double seconds;
extractDegMinSecFrom(value, °rees, &minutes, &seconds);
return QString(tr("%1° %2′ %3″"))
.arg(degrees).arg(minutes).arg(seconds);
}
double DegreeSpinBox::valueFromText(const QString &text) const {
double result = 0;
auto ok = parse(text, &result);
Q_ASSERT(ok);
return result;
}
QValidator::State DegreeSpinBox::validate(QString &text, int &pos) const {
Q_UNUSED(pos)
return parse(text, nullptr) ? QValidator::Acceptable : QValidator::Invalid;
}
void DegreeSpinBox::extractDegMinSecFrom(double value,
int *degrees,
int *minutes,
double *seconds) {
Q_ASSERT(degrees);
Q_ASSERT(minutes);
Q_ASSERT(seconds);
double degreesDouble;
double minutesDouble = std::modf(value, °reesDouble) * 60;
*degrees = static_cast<int>(degreesDouble);
*seconds = std::modf(minutesDouble, &minutesDouble) * 60;
*minutes = static_cast<int>(minutesDouble);
}
bool DegreeSpinBox::parse(QString str, double *result) {
QTextStream stream(&str);
int degrees(0), minutes(0);
double seconds(0);
// %1° %2′ %3″"
QChar symbolDegree(0), symbolMinutes(0), symbolSeconds(0);
stream >> degrees >> symbolDegree
>> ws >> minutes >> symbolMinutes
>> ws >> seconds >> symbolSeconds;
bool success = stream.status() == QTextStream::Ok
&& areSeparatorsValid(symbolDegree, symbolMinutes, symbolSeconds)
&& minutes >=0 && minutes < 60
&& seconds >=0 && seconds < 60;
if (success && result) {
*result = (seconds / 60.0 + minutes) / 60.0 + degrees;
}
return success;
}
bool DegreeSpinBox::areSeparatorsValid(QChar deg, QChar min, QChar sec) {
return deg == QChar(L'°')
&& min == QChar(L'′')
&& sec == QChar(L'″');
}