У меня есть спокойный виджет, который должен только принять шестнадцатеричную строку, как введено. Очень просто ограничить вводимые символы [0-9A-Fa-f]
, но я хотел бы иметь его дисплей с разделителем между "байтами" так, например, если разделитель является пространством и пользовательскими типами 0011223344
Я хотел бы, чтобы редактирование строки отобразилось 00 11 22 33 44
Теперь, если пользователь нажимает клавишу Backspace 3 раза, то я хочу, чтобы она отобразилась 00 11 22 3
.
Я почти имею то, что я хочу, до сих пор существует только одно тонкое вовлечение ошибки с помощью клавиши Delete для удаления разделителя. У кого-либо есть лучший способ реализовать этот блок проверки допустимости? Вот мой код до сих пор:
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
внутренний буфер, но я понятия не имею, где запустить с этого, и я воображаю, нетривиальное обязательство.
В сущности я хотел бы иметь Блок проверки допустимости, который соответствует этому regex: "[0-9A-Fa-f]( [0-9A-Fa-f])*"
но я не хочу, чтобы пользователь когда-либо должен был ввести пространство как разделитель. Аналогично, при редактировании, что они вводят, пробелами нужно управлять неявно.
Эван, попробуйте следующее:
QLineEdit * edt = new QLineEdit( this );
edt->setInputMask( "Hh hh hh hh" );
inputMask позаботится о интервал, а «h» обозначает необязательный шестнадцатеричный символ («H» обозначает необязательный). Единственный недостаток: нужно заранее знать максимальную длину ввода. Мой пример выше позволяет использовать только четыре байта.
С уважением, Робин
Я предложу три подхода:
Вы можете повторно реализовать QLineEdit :: keyPressEvent ()
, чтобы по-разному обрабатывать обратную косую черту, когда символ слева от курсора QLineEdit
находится пробел. Используя этот подход, вы также можете автоматически добавлять пробелы при вводе нового символа.
Другой подход - создать новый слот, связанный с сигналом QLineEdit :: textChanged ()
. Этот сигнал излучается при изменении текста. В этом слоте вы можете обрабатывать создание и удаление пространств в соответствии с вашими потребностями.
Наконец, вы можете создать новый класс, производный от QLineEdit
, который повторно реализует метод QLineEdit :: paintEvent ()
. При таком подходе вы можете отображать пробелы между шестнадцатеричными словами, которые не хранятся в буфере QLineEdit
.