2010-05-03 13 views
7

के लिए QValidator मेरे पास एक क्यूटी विजेट है जो केवल इनपुट के रूप में हेक्स स्ट्रिंग को स्वीकार करना चाहिए। इनपुट वर्णों को [0-9A-Fa-f] पर सीमित करना बहुत आसान है, लेकिन मैं इसे "बाइट्स" के बीच एक डिलीमीटर के साथ प्रदर्शित करना चाहता हूं, उदाहरण के लिए यदि डिलीमीटर एक स्थान है, और उपयोगकर्ता 0011223344 टाइप करता है तो मैं लाइन को संपादित करने के लिए संपादित करना चाहता हूं 00 11 22 33 44 अब यदि उपयोगकर्ता बैकस्पेस कुंजी को 3 बार दबाता है, तो मैं इसे 00 11 22 3 प्रदर्शित करना चाहता हूं।हेक्स इनपुट

I लगभग जो मैं चाहता हूं, अब तक केवल एक सूक्ष्म बग है जिसमें डिलीमीटर को हटाने के लिए डिलीट कुंजी का उपयोग करना शामिल है। क्या किसी के पास इस वैधकर्ता को लागू करने का बेहतर तरीका है? अब इस कोड को काफी कार्यात्मक है के लिए

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 के आंतरिक बफर में संग्रहीत वास्तविक वर्णों से हेक्स स्ट्रिंग का प्रदर्शन अलग होगा, लेकिन मुझे नहीं पता कि इसके साथ कहां से शुरुआत करें और मुझे कल्पना है कि यह एक गैर-मामूली उपक्रम है।

संक्षेप में, मैं एक वैलिडेटर चाहता हूं जो इस रेगेक्स के अनुरूप है: "[0-9A-Fa-f]([0-9A-Fa-f])*" लेकिन मैं नहीं चाहता कि उपयोगकर्ता को कभी भी स्थान को डिलीमीटर के रूप में टाइप करना पड़े। इसी प्रकार, जब वे टाइप करते हैं, तो संपादन को रिक्त स्थान पर प्रबंधित किया जाना चाहिए।

उत्तर

1

मैं तीन तरीकों का प्रस्ताव देगा:

आप अलग बैकस्लैश को संभालने के लिए चरित्र सिर्फ QLineEdit के कर्सर के लिए छोड़ दिया एक जगह नहीं है जब QLineEdit::keyPressEvent() reimplement कर सकते हैं। इस दृष्टिकोण का उपयोग करते हुए, जब आप एक नया अक्षर टाइप करते हैं तो आप स्वचालित रूप से रिक्त स्थान भी जोड़ सकते हैं।

एक और तरीका QLineEdit::textChanged() सिग्नल से जुड़ा एक नया स्लॉट बनाना है। जब टेक्स्ट बदल जाता है तो यह सिग्नल उत्सर्जित होता है। इस स्लॉट में, आप अपनी आवश्यकताओं के अनुसार रिक्त स्थान के निर्माण और हटाना को संभाल सकते हैं।

अंत में, आप QLineEdit से व्युत्पन्न एक नई कक्षा बना सकते हैं जो QLineEdit::paintEvent() विधि को दोहराता है। इस दृष्टिकोण के साथ, आप अपने हेक्स शब्दों के बीच स्थान प्रदर्शित कर सकते हैं जो QLineEdit बफर में संग्रहीत नहीं हैं।

+0

मुझे विश्वास है कि 3 दृष्टिकोण इष्टतम है, कोई मौका आप इस तरह के कोड का उदाहरण देखा है? –

+0

आप http://websvn.kde.org/trunk/KDE/kdeutils/okteta/parts/kbytesedit/ देख सकते हैं, यह प्रासंगिक (लेकिन अधिक जटिल) प्रतीत होता है। – Lohrun

6

इवान, इस प्रयास करें:

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

inputMask रिक्ति का ख्याल रखता है, और "h" एक वैकल्पिक हेक्स चरित्र (एक गैर वैकल्पिक के लिए 'एच') के लिए खड़ा है। केवल दोष: आपको पहले से अधिकतम इनपुट लंबाई जाननी होगी। ऊपर मेरा उदाहरण केवल चार बाइट्स के लिए अनुमति देता है।

सादर, रॉबिन

+0

हाँ, मैंने इसका भी उपयोग करने के बारे में सोचा था। हालांकि अधिकतम लंबाई एक मुद्दा है। काश मैं उस मुखौटा का प्रभाव प्राप्त कर सकता हूं, लेकिन यह कहने में सक्षम हो कि यह दोहराता है: - /। –

संबंधित मुद्दे