У меня есть виджет Qt, который должен принимать в качестве входных данных только шестнадцатеричную строку. Очень просто ограничить вводимые символы [0-9A-Fa-f]
, но я бы хотел, чтобы он отображался с разделителем между байтами, например, если разделитель является пробелом, а пользователь вводит 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])*"
, но я не хочу, чтобы пользователь когда-либо вводил пробел в качестве разделителя. Аналогично, при редактировании того, что они печатают, пробелы должны управляться неявно.