首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Qt:如何将QSpinBox/QDoubleSpinBox设置为角值?

Qt:如何将QSpinBox/QDoubleSpinBox设置为角值?
EN

Stack Overflow用户
提问于 2018-02-24 13:20:25
回答 2查看 1.3K关注 0票数 0

QSpinBox/QDoubleSpinBox的默认值为十进制。可以把十进制改为角度吗?

UPDATE>请看照片。这就是我想在QSpinBox/QDoubleSpinBox中获得的效果。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-24 15:25:09

是的是可能的。只需覆盖valueFromTexttextFromValuevalidate (可选的fixup)。

  • textFromValue应该很容易
  • valueFromTextvalidate需要一个解析功能,因此提取它的通用方法。
  • fixup只在您知道如何纠正用户错误以及validate在某些情况下返回QValidator::中级时才使用。

文档

以下是我的解决方案C++11:

代码语言:javascript
复制
#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文件

代码语言:javascript
复制
#include "degreespinbox.h"
#include <QTextStream>
#include <cmath>

QString DegreeSpinBox::textFromValue(double value) const {
    int degrees, minutes;
    double seconds;
    extractDegMinSecFrom(value, &degrees, &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, &degreesDouble) * 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'″');
}
票数 0
EN

Stack Overflow用户

发布于 2018-02-24 15:20:00

首先,使用单个旋转盒来操作这样的值是不适用的,因为它代表了一个重要的范围。从用户体验的角度来看,为每个组件创建一个专用的旋转盒要容易得多。

第二,如果您仍然坚持使用单个spinbox,那么Qt就没有一个小部件可以做到这一点。但是,您可以轻松地在QDoubleSpinBox上扩展并重载textFromValue()方法,该方法确定旋转框显示的文本,然后您可以从表示位置的任何原始数据中组合一个字符串值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48963318

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档