QT中的64位int Spin Box

Posted

技术标签:

【中文标题】QT中的64位int Spin Box【英文标题】:64bit int Spin Box in QT 【发布时间】:2012-01-13 02:14:30 【问题描述】:

我正在构建一个 Windows 程序,该程序应具有 64 位数值的控件。这些控件应可切换为有符号或无符号。

我找到了两个控件: “旋转框”(int32)和“双旋转框”(双) 使用 double 我可以覆盖范围,但无法处理精度。

有没有办法改变这些控件的数据类型?

是否可以创建一个可以处理有符号和无符号 64 位值的自己的控件? 是否可以创建一个 128 位的 Spin box?

我现在能看到的唯一解决方法是使用字符串控件并手动转换为 INT64 或 UINT64,但我对这个解决方案不太满意

还有其他想法吗?

我在使用 C++ 的 QT 4.7.4 和 VS2010 谢谢

【问题讨论】:

【参考方案1】:

您可以派生QAbstractSpinBox 并至少重新实现虚函数stepBystepEnabled 以及可能的validate()fixup() 以进行输入验证。

【讨论】:

thx... 是否可以将这个新类与 qt 设计器一起使用?我怎样才能在这个“小部件框”工具箱中获得这个新小部件? 您可以编写一个设计器插件,或者只插入一个简单的QWidget 并使用“Promote”功能(左键单击设计器中的小部件)将其替换为您的类,然后添加名为“最小值”、“最大值”和“值”的动态LongLongULongLong 属性。 好的...我将 qspinbox.cpp/.h 复制到我的项目中,并将该类重命名为 CustomSpinBox。然后我添加了这个 moc 东西,就像我为表单所做的那样。在此之后,我在 QT Designer 中添加了一个带有表单的 QWidget,并提升了复制的 custompinbox.h 文件。新的 CustomSpinBox 的编译不起作用。警告 C4273: 'CustomSpinBox::CustomSpinBox' : 不一致的 dll 链接 此构造函数应该与原始旋转框的构造函数完全相同。这对我来说似乎很复杂。是否没有教程或进一步阅读如何扩展标准控件小部件?【参考方案2】:

我不使用修复功能。请参阅我的 Сustom QSpinBox 的代码。 从 QAbstractSpinBox 派生的类 QLongLongSpinBox

别忘了打电话

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

创建 QLongLongSpinBox 之后。

参见 qlonglongspinbox.h 文件:

#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)
;

【讨论】:

嗨,谢谢你的例子!我知道这是几年前的事了,但是有理由提前声明类 QLongLongSpinBoxPrivate 吗?它似乎没有在任何地方使用【参考方案3】:

在 Qt Creator 中使用你的自定义类(Widget):

创建 QWidget 小部件 列表项 在小部件菜单中选择提升为.. 新晋级: QWigdet 升级的类名 QLongLongSpinBox 头文件:编写qlonglongspinbox.h 推广 选择提升为 QLongLongSpinBox 保存

你可以看到

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

和:

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

在 *.ui 文件中

在 ui_*.h 生成文件中你会看到你的类:

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

【讨论】:

【参考方案4】:

只是为了完整起见:每次遇到这样的问题时,请记住(以防其他一切都失败)您可以下载 Qt 源代码并在其中创建自己的 QSpinBox64QSpinBox128 类只需几分钟即可修改所需的部分。

【讨论】:

以上是关于QT中的64位int Spin Box的主要内容,如果未能解决你的问题,请参考以下文章

int 是 64 位 C# 中的 64 位整数吗?

64位机器中的C++ int vs long long

QT的基本数据类型

QT 5.1.1:QWebview 中的复选框在 Win 7 (x64) / Win 8 下显示奇怪的行为

Qt 5.10 集成 Box2D 物理引擎

Qt 4.8.4 Release 版本不适用于 Windows 7 64 位