如何刷新QAbstractSpinBox?

时间:2014-01-24 16:09:14

标签: qt qt4

我需要QSpinBox用于unsigned int。因此我写了简单的课程:

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)。因此,如果我按住Page Up,我的旋转框会获得最大值,这些步骤按钮在我移动鼠标之前不会改变它们的状态。或者,如果值为0,则按键盘上的Page Up或向上箭头键会更改值和文本,但不会更改按钮的状态(向下按钮仍处于禁用状态)。此外,当value == maximum时,虽然函数stepEnabled返回QAbstractSpinBox :: StepDownEnabled(我已经检查过),但两个按钮都被禁用。我究竟做错了什么?如何强制QAbstractSpinBox正确绘制这些按钮?

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

1 个答案:

答案 0 :(得分:1)

我认为您平台上的Qt太旧或者破坏了。它在Qt 4.8.5和Qt 5.2.0上的OS X上都能正常工作。

还有另外两种解决方案:

  1. 如果您不关心全范围的无符号整数,只需使用QSpinBox并设置非负最小值和最大值。就这样。在32位int的平台上,最大int值为2 ^ 31-1,大约是最大uint值的2 ^ 32-1的一半。

  2. 您可以使用QDoubleSpinBox。在您关注的理智平台上,double有超过32位的尾数,因此您可以将其转换为quint32而不会损失精度。

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

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