Tengo un widget Qt que solo debe aceptar una cadena hexadecimal como entrada. Es muy simple restringir los caracteres de entrada a [0-9A-Fa-f]
, pero me gustaría que se muestre con un delimitador entre "bytes", por ejemplo, si el delimitador es un espacio, y el usuario escribe 0011223344
Me gustaría que se muestre la línea de edición 00 11 22 33 44
Ahora, si el usuario presiona la tecla de retroceso 3 veces, entonces quiero que muestre 00 11 22 3
.QValidator para entrada hexadecimal
I casi tengo lo que quiero, hasta ahora solo hay un error sutil que implica el uso de la tecla eliminar para eliminar un delimitador. ¿Alguien tiene una mejor manera de implementar este validador? Aquí está mi código hasta ahora:
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;
}
};
Por ahora este código es lo bastante funcional, pero me gusta tener que funcione al 100% como se esperaba. Obviamente, lo ideal sería simplemente separar la pantalla de la cadena hexadecimal de los caracteres reales almacenados en el búfer interno de QLineEdit
, pero no tengo idea de por dónde empezar y supongo que es una tarea no trivial.
En esencia, me gustaría tener un Validator que se ajuste a esta expresión regular: "[0-9A-Fa-f]([0-9A-Fa-f])*"
pero no quiero que el usuario tenga que escribir un espacio como delimitador. Del mismo modo, al editar lo que escriben, los espacios deben administrarse implícitamente.
Creo que la tercera aproximación es óptima, alguna posibilidad de que usted ha visto ejemplos de este tipo de código? –
Puede consultar http://websvn.kde.org/trunk/KDE/kdeutils/okteta/parts/kbytesedit/, parece ser relevante (pero más complicado). – Lohrun