2010-05-03 168 views
7

我有一個Qt小部件應該只接受一個十六進制字符串作爲輸入。將輸入字符限制爲[0-9A-Fa-f]非常簡單,但我希望在「字節」之間顯示分隔符,例如,如果分隔符是空格,並且用戶類型0011223344我希望行編輯顯示00 11 22 33 44現在,如果用戶按下退格鍵3次,那麼我希望它顯示00 11 22 3QValidator十六進制輸入

差不多有我想要的,到目前爲止只有一個微妙的錯誤,涉及使用刪除鍵刪除分隔符。有沒有人有更好的方法來實現這個驗證器?這裏是我的代碼到目前爲止:

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])*",但我不希望用戶必須鍵入空格作爲分隔符。同樣,編輯它們所鍵入的內容時,空間應該被隱式管理。

回答

1

我會提出了三種方法:

您可以重新實現QLineEdit::keyPressEvent()以不同方式處理反斜槓時只留給QLineEdit的光標字符是一個空間。使用這種方法,您還可以在鍵入新字符時自動添加空格。

另一種方法是創建一個新的插槽,連接到QLineEdit::textChanged()信號。該信號在文本更改時發出。在此插槽中,您可以根據需要處理創建和刪除空格。

最後,您可以創建一個新類,該類自QLineEdit起,重新實現QLineEdit::paintEvent()方法。使用這種方法,您可以在未存儲在QLineEdit緩衝區中的十六進制字之間顯示空格。

+0

我認爲,第三方法是最佳的,你見過這樣的代碼示例任何機會呢? – 2010-05-04 14:45:40

+0

你可以看看http://websvn.kde.org/trunk/KDE/kdeutils/okteta/parts/kbytesedit/,它似乎是相關的(但更復雜)。 – Lohrun 2010-05-04 18:51:05

6

埃文,試試這個:

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

輸入掩碼取間距照顧,和「h」代表一個可選的十六進制字符(「H」的非可選)。唯一的缺點:您必須事先知道最大輸入長度。我上面的例子只允許四個字節。

最好的問候, 羅賓

+0

是的,我也想過使用它。儘管最大長度是一個問題。我希望我能得到這個面具的效果,但能夠說重複: - /。 – 2010-05-04 18:26:13