2013-10-24 7 views
5

की सीमा के भीतर प्रवेश की अनुमति दें मेरे पास QLineEdit एस का एक सेट है जो किसी निश्चित सीमा के भीतर डबल मान स्वीकार करने के लिए माना जाता है, (उदा। -15 से 15)।QDoubleEdit में केवल QDoubleValidator

lineEdit->setValidator(new QDoubleValidator(minVal, maxVal, 5, lineEdit)); 

आदर्श रूप में, लाइन संपादन इस तरह काम करेगा कि केवल सीमा में मूल्यों प्रवेश किया जा सकता:

मैं जब प्रत्येक की स्थापना इन पंक्तियों के साथ कुछ है। जब मैंने इसे आजमाया, मैंने देखा कि वांछित के रूप में केवल संख्याएं टाइप की जा सकती हैं, लेकिन वे अभी भी सीमा से बाहर जा सकते हैं।

कैसे मैं गतिशील रेंज में फिट करने के लिए इनपुट मजबूर कर सकते हैं (उदाहरण के लिए, अगर रेंज -15 से 15 और उपयोगकर्ता के एक 1 है, तो एक 9 टाइप करने के लिए प्रयास करता है, यह काम नहीं करता/9 प्रदर्शित .. लेकिन एक टाइप टाइप करके और फिर, कहें, 2 काम करता है/प्रदर्शित करता है 2.)? क्या मुझे कहीं भी validate() फ़ंक्शन कनेक्ट करने और कॉल करने की आवश्यकता है?

उत्तर

9

है ऐसा इसलिए है क्योंकि QDoubleValidator रिटर्न QValidator::Intermediate अगर मूल्य सीमा के बाहर है और QLineEditQValidator::Intermediate मान स्वीकार करता है।

व्यवहार क्या आप कर सकते हैं चाहता हूँ लागू करने के लिए अपने स्वयं के QDoubleValidator उपवर्ग इस तरह:

class MyValidator : public QDoubleValidator 
{ 
public: 
    MyValidator(double bottom, double top, int decimals, QObject * parent) : 
     QDoubleValidator(bottom, top, decimals, parent) 
    { 
    } 

    QValidator::State validate(QString &s, int &i) const 
    { 
     if (s.isEmpty()) { 
      return QValidator::Intermediate; 
     } 

     bool ok; 
     double d = s.toDouble(&ok); 

     if (ok && d > 0 && d < 15) { 
      return QValidator::Acceptable; 
     } else { 
      return QValidator::Invalid; 
     } 
    } 
}; 

अद्यतन: यह नकारात्मक संकेत मुद्दे का समाधान होगा, और भी स्थान डबल स्वरूपों को स्वीकार करेंगे:

class MyValidator : public QDoubleValidator 
{ 
public: 
    MyValidator(double bottom, double top, int decimals, QObject * parent) : 
     QDoubleValidator(bottom, top, decimals, parent) 
    { 
    } 

    QValidator::State validate(QString &s, int &i) const 
    { 
     if (s.isEmpty() || s == "-") { 
      return QValidator::Intermediate; 
     } 

     QChar decimalPoint = locale().decimalPoint(); 

     if(s.indexOf(decimalPoint) != -1) { 
      int charsAfterPoint = s.length() - s.indexOf(decimalPoint) - 1; 

      if (charsAfterPoint > decimals()) { 
       return QValidator::Invalid; 
      } 
     } 

     bool ok; 
     double d = locale().toDouble(s, &ok); 

     if (ok && d >= bottom() && d <= top()) { 
      return QValidator::Acceptable; 
     } else { 
      return QValidator::Invalid; 
     } 
    } 
}; 
+0

मैं इस अनुकूलित सदस्यों के रूप में न्यूनतम और अधिकतम को बचाने के लिए, क्योंकि वे अलग-अलग हो के लिए मेरे अलग लाइन संपादन निष्पादित के रूप में, और यह एक आकर्षण की तरह काम करता है। हालांकि, उपयोगकर्ता को ऋणात्मक संख्या के लिए प्रारंभिक नकारात्मक चिह्न दर्ज करने की इजाजत देने में परेशानी होती है। मैं सोच रहा हूं कि सिर्फ इस समाधान की लागत हो सकती है .. – nicole

+0

धन्यवाद! मैंने QDoubleValidator, setNotation (QDoubleValidator :: StandardNotation), और QLineEdit इनपुट मास्क पर एक दिन बर्बाद कर दिया है। जैसा कि मैंने उम्मीद की थी, इसमें से कोई भी व्यवहार नहीं करता था। चरित्र प्रविष्टि द्वारा पुराने स्कूल-पार्स चरित्र को लागू करना जल्दबाजी में होता। वास्तव में काम करने वाले समाधान के लिए धन्यवाद! (मैंने दशमलव परिवर्तन के बाद "-", फिक्स्ड चार के अलावा "+" को अनुमति देने के लिए कुछ बदलाव किए हैं, और शीर्ष और नीचे सहित श्रेणी परीक्षण बनाया है) –

3

मैंने ऊपर उत्कृष्ट श्रेणी की कोशिश की और इसे अभी भी कुछ संपादन की आवश्यकता है। दशमलव बिंदु खोज "शीर्ष" द्वारा निर्दिष्ट सीमा को कम कर रही थी क्योंकि जब कोई दशमलव बिंदु नहीं होता है तो यह "-1" लौटाता है। मैंने एक सशर्त बयान जोड़ा जो इसे हल करता है।

इसके अलावा, यह अभी भी उस मामले के लिए tweaked की जरूरत है जहां उपयोगकर्ता दशमलव बिंदु को हटाने की कोशिश करता है और परिणामी मान सीमा से बड़ा है। अभी यह केवल उस मूल्य को प्रतिबंधित करता है जो इसे अधिकतम मूल्य में बदलने की बजाय मुझे अधिक सहज लगता है।

class MyValidator : public QDoubleValidator 
{ 
    public: 
    MyValidator(double bottom, double top, int decimals, QObject * parent) : 
    QDoubleValidator(bottom, top, decimals, parent) 
    { 
    } 

    QValidator::State validate(QString &s, int &i) const 
    { 
     if (s.isEmpty() || s == "-") { 
      return QValidator::Intermediate; 
     } 

     QLocale locale; 

     QChar decimalPoint = locale.decimalPoint(); 
     int charsAfterPoint = s.length() - s.indexOf(decimalPoint) -1; 

     if (charsAfterPoint > decimals() && s.indexOf(decimalPoint) != -1) { 
      return QValidator::Invalid; 
     } 

     bool ok; 
     double d = locale.toDouble(s, &ok); 

     if (ok && d >= bottom() && d <= top()) { 
      return QValidator::Acceptable; 
     } else { 
      return QValidator::Invalid; 
     } 
    } 
}; 
2

मैं लगभग एक दिन बिताया जब QLineEdit इनपुट के स्वीकार्य सीमा के लिए जाँच उचित प्रयोक्ताओं की राय के साथ QDoubleValidator काम करने के लिए कोशिश कर रहा। क्यूटी निर्धारित वैधकर्ता का उपयोग करने के मेरे प्रयास :: फिक्सअप समय की बर्बादी बन गया। इससे पहले इस धागे में उत्तर अधिक उपयोगी हैं लेकिन अभी भी कमियां हैं। अंत में मैंने एक अलग और सरल दृष्टिकोण का चयन किया।

  1. QDoubleEdit QDoubleValidator के साथ सुसज्जित करें जो कोई सीमा जांच नहीं करता है।
  2. QLineEdit संपादन के लिए हैंडलर में परिभाषित सिग्नल रेंज की जांच करता है और यदि आवश्यक है तो QLineEdit टेक्स्ट का रीसेट करें।

यह दृष्टिकोण अवैध पात्रों के टाइपिंग को अस्वीकार करता है, स्थानीयकरण की देखभाल करता है और वांछित सीमा के बाहर मूल्यों को सुधारता है।

मेरे लिए अच्छा काम करता है।

3

उप-वर्गीकरण के बिना भी ऐसा करना संभव है।

lineEdit = new QLineEdit(); 
connect(lineEdit,SIGNAL(textChanged(QString)), this, SLOT(textChangedSlot(QString))); 

QDoubleValidator *dblVal = new QDoubleValidator(minVal, maxVal, 1000, lineEdit); 
dblVal->setNotation(QDoubleValidator::StandardNotation); 
dblVal->setLocale(QLocale::C); 
lineEdit->setValidator(dblVal); 

लोकेल की सेटिंग महत्वपूर्ण हो सकती है क्योंकि यह परिभाषित करता है कि कौन से वर्ण दशमलव विभाजक के रूप में व्याख्या किए जाते हैं। इनपुट स्ट्रिंग का प्रारूप परिभाषित करता है कि कौन से लोकेशंस का उपयोग किया जाना चाहिए।

QString str = lineEdit->text(); 
int i = 0; 
QDoubleValidator *val = (QDoubleValidator *) lineEdit->validator(); 
QValidator::State st = val->validate(str, i); 

if (st == QValidator::Acceptable) { 
    // Validation OK 
} else { 
    // Validation NOK 
} 

इस मामले भी QValidator :: मध्यवर्ती राज्य एक असफल मामले के रूप में व्याख्या की है में:

textChangedSlot में, हम इनपुट इस तरह से सत्यापित कर सकें।

यदि हम टेक्स्ट चेंजड-सिग्नल को टेक्स्ट चेंग्डस्लॉट से कनेक्ट करते हैं, तो प्रत्येक इनपुट फ़ील्ड परिवर्तन के बाद सत्यापन किया जाता है। हम संपादन फ़िनिश() या रिटर्नप्रेस() -सिग्नल को सत्यापन स्लॉट में भी कनेक्ट कर सकते हैं। उस स्थिति में, सत्यापन तब किया जाता है जब उपयोगकर्ता स्ट्रिंग को संपादित करना बंद कर देता है।

1

VVV के जवाबनिकोल की orignal प्रश्न के लिए महान काम करता है। यह तब होता है जब सीमा नकारात्मक से सकारात्मक होती है।

हालांकि के रूप में QDoubleValidator के लिए एक सामान्य समाधान यह एक ओर प्रभाव पड़ता है रेंज सकारात्मक से सकारात्मक है जब:

उदाहरण:रेंज: [87.5 ... 1000.0], इनपुट: " 15 "(इंटरमीडिएट के रूप में मूल्य 150 तक पहुंचने के लिए)

QLineEdit निचली सीमा के नीचे चला जाता है (या खाली शुरू होता है) इनपुट इनपुट अस्वीकार कर दिया जाएगा। इसलिए मैं VVVका समाधान बढ़ाया एक सामान्य समाधान के लिए:

/* 
* Empty string and the negative sign are intermediate 
*/ 
if(input.isEmpty() || input == "-") 
{ 
    return QValidator::Intermediate; 
} 
/* 
* Check numbers of decimals after the decimal point 
* and the number of decimal points 
*/ 
QChar decimalPoint = locale().decimalPoint(); 
if(input.count(decimalPoint, Qt::CaseInsensitive) > 1) 
{ 
    return QValidator::Invalid; 
} 
else if(input.indexOf(decimalPoint) != -1) 
{ 
    const int charsAfterPoint = input.length() - input.indexOf(decimalPoint) - 1; 
    if(charsAfterPoint > decimals()) 
    { 
     return QValidator::Invalid; 
    } 
} 
/* 
* Check for valid double conversion and range 
*/ 
bool ok; 
const double d = locale().toDouble(input, &ok); 
if(ok && d <= top()) 
{ 
    if(d >= bottom()) 
    { 
     return QValidator::Acceptable; 
    } 
    else 
    { 
     return QValidator::Intermediate; 
    } 
} 
else 
{ 
    return QValidator::Invalid; 
} 
0

मैं जब एक समाधान है, जो वैज्ञानिक और साथ ही मानक संकेत का समर्थन करता है के लिए खोज इस समाधान बारे में जाना। यह पेट्री पायओरी द्वारा दिए गए सुझाव से प्रेरित है, यहां एक समाधान है, जो editingFinished सिग्नल का उपयोग करता है।

मैं validate अतिभारित है सुनिश्चित करने के लिए भी जब मूल्य सीमा से बाहर है कि QValidator::Acceptable दिया जाता है। यह editingFinished को ट्रिगर करता है, जिसे मैं आउटपुट को छोटा करने के लिए उपयोग करता हूं। इस रास्ते में, दोनों वैज्ञानिक और मानक संकेतन वास्तव में इस्तेमाल किया जा सकता द्वारा QDoubleValidator

#include <QDoubleValidator> 

class TruncationValidator : public QDoubleValidator 
{ 
    Q_OBJECT 
public: 
    explicit TruncationValidator(QObject *parent = 0) : QDoubleValidator(parent) { 
     connect(this->parent(), SIGNAL(editingFinished()), this, SLOT(truncate())); 
    } 
    TruncationValidator(double bottom, double top, int decimals, QObject * parent) : QDoubleValidator(bottom, top, decimals, parent) { 
     connect(this->parent(), SIGNAL(editingFinished()), this, SLOT(truncate())); 
    } 

    QValidator::State validate(QString &s, int &i) const { 
     QValidator::State state = QDoubleValidator::validate(s,i); 

     if (s.isEmpty()) { 
     return state; 
     } 

     bool ok; 
     double d = s.toDouble(&ok); 

     if (ok) { 
     // QDoubleValidator returns QValidator::Intermediate if out of bounds 
     return QValidator::Acceptable; 
     } 
     return state; 
    } 

private slots: 
    void truncate() { 
     QLineEdit* le = dynamic_cast<QLineEdit*>(parent()); 
     if (le) { 
     QString s = le->text(); 
     bool ok; 
     double d = s.toDouble(&ok); 
     if (ok) { 
      if (d > this->top() || d < this->bottom()) { 
      d = std::min<double>(d, this->top()); 
      d = std::max<double>(d, this->bottom()); 
      le->setText(QString::number(d)); 
      } 
     } 
     } 
    } 
private: 
}; 
संबंधित मुद्दे