2014-01-24 104 views
0

我需要QSpinBox for unsigned int。所以我写了简单的课:如何刷新QAbstractSpinBox?

class UnsignedSpinBox : public QAbstractSpinBox { 
private: 
    uint32_t value = 0; 
    uint32_t minimum = 0; 
    uint32_t maximum = 100; 
private: 
    void stepBy(int steps) { 
    if (steps < 0 && (uint32_t)(-1 * steps) > value - minimum) 
     value = minimum; 
    else if (steps > 0 && maximum - value < (uint32_t)steps) 
     value = maximum; 
    else 
     value += steps; 
    lineEdit()->setText(QString::number(value)); 
    } 
    StepEnabled stepEnabled() const { 
    if (value < maximum && value > minimum) 
     return QAbstractSpinBox::StepUpEnabled | QAbstractSpinBox::StepDownEnabled; 
    else if (value < maximum) 
     return QAbstractSpinBox::StepUpEnabled; 
    else if (value > minimum) 
     return QAbstractSpinBox::StepDownEnabled; 
    else 
     return QAbstractSpinBox::StepNone; 
    } 
    QValidator::State validate(QString &input, int &) const { 
    if (input.isEmpty()) 
     return QValidator::Intermediate; 
    bool ok = false; 
    uint32_t validateValue = input.toUInt(&ok); 
    if (!ok || validateValue > maximum || validateValue < minimum) 
     return QValidator::Invalid; 
    else 
     return QValidator::Acceptable; 
    } 

public: 
    UnsignedSpinBox(QWidget* parent = 0) : QAbstractSpinBox(parent) { 
    lineEdit()->setText(QString::number(value)); 
    } 
    virtual ~UnsignedSpinBox() { } 
}; 

在gerenal它工作正常,但它有一个缺点。只有鼠标移动后,才会刷新步骤按钮(每秒调用一次功能stepEnabled)。因此,如果我保持向上翻页,我的旋转框将获得最大值,并且这些步骤按钮在我移动鼠标之前不会更改它们的状态。或者,如果值为0,则按下键盘上的向上或向上箭头键将更改值和文本,但不会更改按钮的状态(向下按钮仍处于禁用状态)。此外,当价值==最大两个按钮都被禁用,虽然功能stepEnabled返回QAbstractSpinBox :: StepDownEnabled(我已经检查过)。我究竟做错了什么?我如何强制QAbstractSpinBox正确绘制这些按钮?

P.S.我使用Debian。但我不认为这是重要的,因为QSpinBox工作正常

回答

1

我认为你的平台上的Qt要么太旧,要么破坏。它在OS X上工作正常,在Qt 4.8.5和Qt 5.2.0上。

还有其他两种解决方案:

  1. 如果你不关心全方位无符号整数,只需使用QSpinBox,并设置非负的最小值和最大值。就这样。在具有32位int的平台上,最大值为int,值为2^31-1,约为最大值的uint的一半。您可以使用QDoubleSpinBox。在你关心的理智平台上,double有超过32位的尾数,所以你可以将它转换为quint32而不会损失精度。

    如果您想确定,只需在代码的任意位置添加static_assert(sizeof(double)>4)即可。

    如果担心表现,那真的没关系。计算以用户输入事件的速率执行:这是每秒几十次双操作。没关系。

+0

我在Windows 7 Professional上试过这个类......这些按钮根本不会被禁用(看起来在使用Qt时Windows上没有这个功能)。我不想使用QDoubleSpinBox,因为双重计算比整数慢... 在Linux和Windows上,我使用Qt 5.2.0和Qt Creator 3.0.0。但专业文件包含行'greaterThan(QT_MAJOR_VERSION,4):QT + =部件' – user2717575

+0

你用C++ 11编译我的代码吗? – user2717575

+0

@ user2717575:在这里,C++ 11是无关紧要的。您在Windows *上使用的*风格可能不会使*按钮被禁用时显而易见。尽管如此,他们仍然残疾。 –