我有一个Qt小部件,它只接受十六进制字符串作为输入。将输入字符限制为[0-9A-Fa-f]
非常简单,但是我希望它在“bytes”之间显示分隔符,例如,如果分隔符是空格,并且用户键入0011223344
我希望行编辑显示00 11 22 33 44
现在,如果用户按下退格键3次,那么我希望它显示00 11 22 3
。
我几乎拥有我想要的东西,到目前为止只有一个微妙的错误,涉及使用删除键删除分隔符。有没有人有更好的方法来实现这个验证器?到目前为止,这是我的代码:
class HexStringValidator : public QValidator {
public:
HexStringValidator(QObject * parent) : QValidator(parent) {}
public:
virtual void fixup(QString &input) const {
QString temp;
int index = 0;
// every 2 digits insert a space if they didn't explicitly type one
Q_FOREACH(QChar ch, input) {
if(std::isxdigit(ch.toAscii())) {
if(index != 0 && (index & 1) == 0) {
temp += ' ';
}
temp += ch.toUpper();
++index;
}
}
input = temp;
}
virtual State validate(QString &input, int &pos) const {
if(!input.isEmpty()) {
// TODO: can we detect if the char which was JUST deleted
// (if any was deleted) was a space? and special case this?
// as to not have the bug in this case?
const int char_pos = pos - input.left(pos).count(' ');
int chars = 0;
fixup(input);
pos = 0;
while(chars != char_pos) {
if(input[pos] != ' ') {
++chars;
}
++pos;
}
// favor the right side of a space
if(input[pos] == ' ') {
++pos;
}
}
return QValidator::Acceptable;
}
};
现在这段代码已经足够功能了,但我很乐意让它按预期工作100%。显然,理想的是将十六进制字符串的显示与存储在QLineEdit
的内部缓冲区中的实际字符分开,但我不知道从哪里开始,我想这是一项非平凡的任务。
本质上,我希望有一个符合此正则表达式的Validator:"[0-9A-Fa-f]( [0-9A-Fa-f])*"
但我不希望用户必须输入空格作为分隔符。同样,在编辑它们键入的内容时,应该隐式管理这些空格。
答案 0 :(得分:6)
QLineEdit * edt = new QLineEdit( this );
edt->setInputMask( "Hh hh hh hh" );
inputMask负责间距,“h”代表可选的十六进制字符(“H”代表非可选字符)。唯一的缺点:您必须提前知道最大输入长度。我上面的例子只允许四个字节。
祝你好运, 罗宾
答案 1 :(得分:1)
我将提出三种方法:
当刚刚离开QLineEdit::keyPressEvent()
光标的角色是空格时,您可以重新实现QLineEdit
以不同方式处理反斜杠。使用此方法,您还可以在键入新字符时自动添加空格。
另一种方法是创建一个连接到QLineEdit::textChanged()
信号的新插槽。更改文本时会发出此信号。在此插槽中,您可以根据需要处理空间的创建和删除。
最后,您可以创建一个新类,该类派生自重新实现QLineEdit
方法的QLineEdit::paintEvent()
。使用此方法,您可以显示未存储在QLineEdit
缓冲区中的十六进制单词之间的空格。
答案 2 :(得分:1)
Robin的解决方案很好并且可行。但我认为你可以做到最好!
使用此作为输入掩码:
ui->lineEdit->setInputMask("HH-HH-HH-HH");
,然后在ui中,右键单击lineEdit->转到Slots ...-> textChanged。 在slot函数中编写以下代码:
int c = ui->lineEdit->cursorPosition();
ui->lineEdit->setText(arg1.toUpper());
ui->lineEdit->setCursorPosition(c); // to not jump cursor's position
现在,您有一个带有十六进制输入的lineEdit(大写字母,带有破折号)。
编码时间不错:)