Ho un widget Qt che dovrebbe accettare solo una stringa esadecimale come input. È molto semplice limitare i caratteri di input a [0-9A-Fa-f]
, ma mi piacerebbe che fosse visualizzato con un delimitatore tra "byte", ad esempio se il delimitatore è uno spazio e l'utente digita 0011223344
Desidero visualizzare la riga 00 11 22 33 44
Ora se l'utente preme il tasto backspace 3 volte, allora voglio che visualizzi 00 11 22 3
.QValidatore per ingresso esadecimale
I quasi avere quello che voglio, finora c'è solo un bug sottile che comporta l'utilizzo del tasto di cancellazione per rimuovere un delimitatore. Qualcuno ha un modo migliore per implementare questo validatore? Ecco il mio codice finora:
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;
}
};
Per ora questo codice è abbastanza funzionale, ma mi piacerebbe farlo funzionare al 100% come previsto. Ovviamente l'ideale sarebbe semplicemente separare la visualizzazione della stringa esadecimale dai caratteri effettivi memorizzati nel buffer interno di QLineEdit
ma non ho idea di dove cominciare e immagino sia un'impresa non banale.
In sostanza, mi piacerebbe avere un Validatore conforme a questa espressione regolare: "[0-9A-Fa-f]([0-9A-Fa-f])*"
ma non voglio che l'utente debba mai digitare uno spazio come delimitatore. Allo stesso modo, quando si modifica ciò che tipizzano, gli spazi dovrebbero essere gestiti implicitamente.
Credo che il terzo approccio è ottimale, ogni possibilità che avete visto esempi di tale codice? –
Puoi guardare http://websvn.kde.org/trunk/KDE/kdeutils/okteta/parts/kbytesedit/, sembra essere rilevante (ma più complicato). – Lohrun