QSpinBox中的验证

时间:2012-09-27 07:22:07

标签: c++ qt validation qspinbox

我有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值应为奇数的消息。我在statusTip中找到了QWidget属性,但无法找到如何使用它的示例。

5 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

您可以使用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 );
    }
}

现在,如果您想保留旧值以防使用输入偶数,您必须继承QSpinBox,或使用事件过滤器来捕获关键新闻事件,然后执行之前,值会发生变化。

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

spinbox with tooltip

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

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

答案 2 :(得分:0)

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

修复程序可能正在使用计时器来更正spinbox中的值。例如。一旦我们收到valueChanged信号,我们就会重启一个带有(500ms)timout的定时器(如果输入的速度足够快,定时器只会触发一次)。我们检查并更正定时器超时时隙中的输入。

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

在python中,我使用了spinbox的editingFinished属性,如下解决了此问题。仅在您按Enter键或将焦点移离框时才触发信号。在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)

希望有帮助。