【问题标题】:Validation in QSpinBoxQSpinBox 中的验证
【发布时间】:2012-09-27 07:22:07
【问题描述】:

我有QSpinBox,它应该只接受奇数,所以我将初始值设置为 3 并设置为 2。

QSpinBox* spinBox = new QSpinBox;
spinBox->setValue(3);
spinBox->setSingleStep(2);

当我使用旋转框箭头修改值时,一切正常。但是当我从键盘输入值时,它不能取奇数。

那么是否可以在不继承QSpinBox 并重新定义其validate 方法的情况下设置满足我要求的验证?

如果值是奇数,我当前的解决方案是检查槽:

void MyWidget::slotSetSpinBoxValue(int value)
{
    if(value%2 != 0)
    {
         //call function which takes only odd values
    }
    else
    {
        //here I want to show some kind off message that value can only be odd
        //call function with --value parameter
    }
}

第二个问题是如何为QSpinBox 显示一些提示?我想显示类似工具提示的提示,其中显示QSpinBox 值应该是奇数的消息。我在QWidget 中找到了statusTip 属性,但找不到如何使用它的示例。

【问题讨论】:

    标签: c++ qt validation qspinbox


    【解决方案1】:

    关于 Richard 的评论,我认为 ctrl->setKeyboardTracking(false) 可以绕过每次击键时会发生的检查,并且只允许在最后进行验证。

    【讨论】:

      【解决方案2】:

      您可以连接到 editingFinished 信号并修复它:

      void Obj::onSpinEditFinished()
      {
          int val = ui->spinPoints->value();
          if(val % 2 == 0)
              ui->spinPoints->setValue(val-1);
      }
      

      【讨论】:

        【解决方案3】:

        我认为正确的答案并不完美。它使你无法输入像“12”这样的值,因为当输入“1”时会触发值改变信号,并且它将被更正为“0”,因为1是奇数。

        修复可能是使用计时器来更正旋转框中的值。例如。一旦我们收到 valueChanged 信号,我们就会用(500ms)超时重新启动一个定时器(如果你输入足够快,定时器只会触发一次)。我们检查并更正定时器超时槽中的输入。

        【讨论】:

        • 我不认为设置计时器是一个可靠的解决方案,因为时间似乎太随意了。
        • 你说得对,理查德,当你开始从键盘输入文本时,正确答案不起作用。我通过将 QSpinBox 替换为 QComboBox 来解决此问题,其中只有偶数...
        【解决方案4】:

        您可以使用valueChanged() 插槽来解决问题:

        void MainWindow::on_spinBox_valueChanged(int arg1)
        {
            if( arg1 % 2 == 0)
            {
                //for even values, show a message 
                QMessageBox b;
                b.setText("Only odd values allowed!");
                b.exec();
                //and then decrease the value to make it odd 
                ui.spinBox->setValue( arg1 - 1 );
            }
        }
        

        现在,如果您想保留旧值以防 used 输入偶数,则必须从 QSpinBox 继承,或使用事件过滤器来捕获按键事件,并在 before 值被更改。

        要在用户将鼠标悬停在旋转框上时显示消息,您需要设置框的toolTip,其中包含将要显示的字符串:

        更新: 如果您不想要消息框,您可以:

        • 使用QStatusBar。它可以显示仅持续一段时间的消息(您传递它)。它的缺点是消息会出现在窗口底部的栏上,而不是靠近旋转框。
        • 在旋转框下方放置一个标签。当用户输入无效值时,将标签的文本设置为“只允许奇数值”之类的内容,并在用户输入正确值时设置空字符串。您也可以动态执行此操作:
          1. 用户输入了错误的值
          2. 创建带有警告文本的QLabel,并设置Qt::WA_DeleteOnClose 标志,这样标签在关闭时会自行删除。
          3. 使用singleShot 创建一个QTimer,并在几秒钟后将其设置为触发(当您希望消息消失时)
          4. 将计时器的信号连接到标签的close() 插槽。当计时器到期时,标签将被关闭,并且感谢WA_DeleteOnClose,将被删除。

        【讨论】:

        • MessageBox 对我来说是显而易见的解决方案。但我不想抛出一些模态窗口,因为它可能很烦人。我想在 toolTip 中做一些提示。但是设置 toolTip 会在鼠标悬停时显示它。而且我只想在用户输入为偶数时显示提示一段时间。但是我看做起来不容易?
        • 好吧,有了这个技巧,它似乎可以模仿我想要达到的效果。
        【解决方案5】:

        在 python 中,我使用 spinbox 的 editingFinished 属性解决了这个问题。这仅在您按下回车键或将焦点从框移开时才会触发信号。在 python 中,我必须传递函数引用,否则传递的值不是更新的,而是初始化时的。:

        class SpinboxExample:
            def __init__(self)
                spinbox = QSpinBox()
                spinbox.editingFinished.connect(
                    lambda value=spinbox.value, set_spinbox_val=spinbox.setValue:
                    self.value_changed_spinbox(value,set_spinbox_val, set_slider_val)
                    )
        

        然后我有一个回调函数,它检查数字是否为奇数,如果没有改变旋转框中的值使其为奇数。

            def value_changed_spinbox(self, get_value,set_spinbox_value):
                value=get_value()
                if value % 2 == 0:
                    value += 1
                    set_spinbox_value(value)
        

        希望对您有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-07-27
          • 1970-01-01
          • 2020-02-07
          • 2015-01-31
          • 2013-10-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多