2010-05-03 13 views
7

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.

Respuesta

1

que propondrá tres enfoques:

Puede reimplementar la QLineEdit::keyPressEvent() barra invertida para manejar de manera diferente cuando el personaje justo a la izquierda del cursor a la QLineEdit 's es un espacio. Usando este enfoque, también puede agregar espacios automáticamente cuando se escribe un nuevo carácter.

Otro enfoque es crear una nueva ranura, conectada a la señal QLineEdit::textChanged(). Esta señal se emite cuando se cambia el texto. En esta ranura, puede gestionar la creación y eliminación de espacios según sus necesidades.

Finalmente, puede crear una nueva clase, derivada de QLineEdit que vuelve a aplicar el método QLineEdit::paintEvent(). Con este enfoque, puede mostrar espacio entre sus palabras hexadecimales que no están almacenadas en el búfer QLineEdit.

+0

Creo que la tercera aproximación es óptima, alguna posibilidad de que usted ha visto ejemplos de este tipo de código? –

+0

Puede consultar http://websvn.kde.org/trunk/KDE/kdeutils/okteta/parts/kbytesedit/, parece ser relevante (pero más complicado). – Lohrun

6

Evan, intente esto:

QLineEdit * edt = new QLineEdit(this); 
edt->setInputMask("Hh hh hh hh"); 

La máscara de entrada se encarga de la separación, y la "h" significa un carácter hexadecimal opcional (la "H" para un no-opcional). Único inconveniente: debe conocer la longitud máxima de entrada por adelantado. Mi ejemplo anterior solo permite cuatro bytes.

Saludos, Robin

+0

Sí, pensé en usar eso también. Sin embargo, la duración máxima es un problema. Desearía poder obtener el efecto de esa máscara, pero ser capaz de decirlo se repite: - /. –

Cuestiones relacionadas