[ fromfile: validation.xml id: home-made-valid ]
When the requirements for validating user input go beyond simple numeric range-checking or validation with a regular expression, you can define your own validator class by deriving from QValidator.
For the next example, we define a palindrome as a string that reads the same backward or forward, ignoring case, white space, and punctuation.
Unfortunately, it is not possible for a single regular expression to determine whether strings of arbitrary size are palindromes.
Example 14.9 shows Palindate
, a QValidator that can used to verify if a given string is a palindrome.
Example 14.9. src/validate/palindrome/palindate.h
#include <QValidator> #include <QString> class Palindate : public QValidator { Q_OBJECT public: explicit Palindate(QObject* parent = 0); QValidator::State validate(QString& input, int&) const; };
<include src="src/validate/palindrome/palindate.h" href="src/validate/palindrome/palindate.h" id="palindateh" allfiles="1" mode="cpp"/>
The QValidator class has one required override, validate()
, defined in Example 14.10.
It makes a lowercase copy, inpStr
, of the given string, and removes all white space and punctuation from it.
It then compares inpStr
with the string revStr
, which contains the same characters but in reverse order.
Example 14.10. src/validate/palindrome/palindate.cpp
[ . . . . ] QValidator::State Palindate::validate(QString& str, int& ) const { QString inpStr(str.toLower()); QString skipchars("-_!,;. \t"); foreach(QChar ch, skipchars) inpStr = inpStr.remove(ch); QString revStr; for(int i=inpStr.length(); i > 0; --i) revStr.append(inpStr[i-1]); if(inpStr == revStr) return Acceptable; else return Intermediate; }
<include src="src/validate/palindrome/palindate.cpp" href="src/validate/palindrome/palindate.cpp" id="palindatecpp" mode="cpp"/>
Example 14.11 defines a widget that contains a QLineEdit to test the validator.
Example 14.11. src/validate/palindrome/palindromeform.h
[ . . . . ] class PalindromeForm : public QWidget { Q_OBJECT public: PalindromeForm(QWidget* parent=0); QString getPalindrome(); public slots: void showResult(); void again(); private: Palindate* m_Palindate; QLineEdit* m_LineEdit; QLabel* m_Result; QString m_InputString; void setupForm(); }; [ . . . . ]
<include src="src/validate/palindrome/palindromeform.h" href="src/validate/palindrome/palindromeform.h" id="pformh" mode="cpp"/>
In Example 14.12, the widgets are set up, and a Palindate validator is set on the QLineEdit.
Example 14.12. src/validate/palindrome/palindromeform.cpp
[ . . . . ] PalindromeForm::PalindromeForm(QWidget* parent) : QWidget(parent), m_Palindate(new Palindate), m_LineEdit(new QLineEdit), m_Result(new QLabel) { setupForm(); } void PalindromeForm::setupForm() { setWindowTitle("Palindrome Checker"); m_LineEdit->setValidator(m_Palindate); connect(m_LineEdit, SIGNAL(returnPressed()), this, SLOT(showResult())); [ . . . . ] } void PalindromeForm::showResult() { QString str = m_LineEdit->text(); int pos(0); if(m_Palindate->validate(str,pos) == QValidator::Acceptable) { m_InputString = str; m_Result->setText("Valid Palindrome!"); } else { m_InputString = ""; m_Result->setText("Not a Palindrome!"); } } [ . . . . ]
<include src="src/validate/palindrome/palindromeform.cpp" href="src/validate/palindrome/palindromeform.cpp" id="pformcpp" mode="cpp"/>
Figure 14.5 shows a screenshot of the running application.
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |