使用HexStringValidator的Qt示例失败

时间:2019-04-17 08:13:39

标签: qt hex customvalidator

我在此示例中使用以下代码:https://doc.qt.io/qt-5/qtserialbus-can-example.html

enum {
    MaxPayload = 8,
    MaxPayloadFd = 64
};

HexStringValidator::HexStringValidator(QObject *parent) :
    QValidator(parent),
    m_maxLength(MaxPayload)
{
}

HexStringValidator::HexStringValidator(QObject *parent, uint maxLength) :
    QValidator(parent),
    m_maxLength(maxLength)
{
}

class HexStringValidator : public QValidator
{
    Q_OBJECT

public:
    explicit HexStringValidator(QObject *parent = nullptr);
    explicit HexStringValidator(QObject *parent, uint maxLength);

    QValidator::State validate(QString &input, int &pos) const;

    void setMaxLength(int maxLength);

private:
    uint m_maxLength = 0;
};

问题出在此函数中: 我有一个带有此验证器的lineedit,并使用有效的十六进制字符串调用它。

ui->lineEditCANCommand->setValidator(new HexStringValidator(this, 4));
ui->lineEditCANCommand->setText("000003e9");

QValidator::State HexStringValidator::validate(QString &input, int &pos) const
{
    const int maxSize = 2 * static_cast<int>(m_maxLength);
    const QChar space = QLatin1Char(' ');
    QString data = input;
    data.remove(space);

    if (data.isEmpty())
        return Intermediate;

    // limit maximum size and forbid trailing spaces
    if ((data.size() > maxSize) || (data.size() == maxSize && input.endsWith(space)))
        return Invalid;

    // check if all input is valid
    const QRegularExpression re(QStringLiteral("^[[:xdigit:]]*$"));
    if (!re.match(data).hasMatch())
        return Invalid;

    // insert a space after every two hex nibbles
    const QRegularExpression insertSpace(QStringLiteral("(?:[[:xdigit:]]{2} )*[[:xdigit:]]{3}"));
    if (insertSpace.match(input).hasMatch()) {
        input.insert(input.size() - 1, space);
        pos = input.size();
    }

    return Acceptable;
}

该功能应该将其更改为“ 00 00 03 e9”

但是它不断运行并创造了

  

000003e 9

     

000003e 9

     

000003e 9

     

000003e 9

出了什么问题?请注意,这段代码来自Qt,而不是我的。

1 个答案:

答案 0 :(得分:-1)

有与此问题相关的 issue 和以下两个提交:
Can example: Fix crash in payload hex editor,
CAN Example: Properly format payload hex string
可以在未来的版本 (>6.2.0) 中进行测试。

首先,我将 insertSpace 正则表达式更改为 threeDigits

QStringLiteral("[[:xdigit:]]{3}")

如果连续添加 3 位数字,则插入空格:

input.insert(match.capturedEnd() - 1, space);

这解决了崩溃问题(无限递归)。
然后我添加了辅助条件 isEvenHex 和格式化程序 formatHexData 以及 oneDigitAndSpacethreeDigits 正则表达式,删除所有额外的空格并在每两个十六进制字节后添加空格。我分别在 text changesendButton 点击时调用它们:

connect(m_ui->payloadEdit, &QLineEdit::textChanged, frameIdOrPayloadChanged);

connect(m_ui->sendButton, &QPushButton::clicked, [this]() {
...
m_ui->payloadEdit->setText(formatHexData(data));
...
}

我觉得还是看源码比较好。如果没有,我可以提供更多细节。
我可以问一个问题 - 你对验证器有什么期望 - 在 send button 按下后不允许写入额外的空间或删除所有额外的空间?