-
Ip Address Validation
I've checked a lot of sites, but haven't found a definitive IP Address validation routine. I'm using the IPAddress mask, but is there a better way to validate the address than capturing the finishedEditing signal and doing it via code (x > 0 && x< 256)?
Also, how do I tell Qt to keep the focus in the current field if the entry is in error? lineEdit.SetFocus() gives me recursion problems with my finishedEditing signal.
- BRC
-
Re: Ip Address Validation
Quote:
Originally Posted by
bruccutler
...is there a better way to validate the address than capturing the finishedEditing signal and doing it via code (x > 0 && x< 256)?
Also, how do I tell Qt to keep the focus in the current field if the entry is in error? lineEdit.SetFocus() gives me recursion problems with my finishedEditing signal.
A QRegExpValidator might be what you're looking for in both cases here.
-
Re: Ip Address Validation
No - reg expression will check the values, but won't do a full check for 1-255 for all values. At least not one that I've ever seen.
- Bruce
-
Re: Ip Address Validation
Quote:
Originally Posted by
bruccutler
No - reg expression will check the values, but won't do a full check for 1-255 for all values.
You could, but it would be a fairly complex regular expression.
-
Re: Ip Address Validation
So - what is the right way to do this? I think I will set it aside, since I'm sure someone out there has solved this problem with Qt.
- BRC
-
Re: Ip Address Validation
I think you could do it with the combination of a masked line edit, and a QRegExpValidator that checks for a regex like this: (?:1\d?\d?|2(?:[0-4]\d?|[6789]|5[0-5]?)?|[3-9]\d?|0)(?:\.(?:1\d?\d?|2(?:[0-4]\d?|[6789]|5[0-5]?)?|[3-9]\d?|0)){3}
That said, I haven't tried this myself, so who knows... ;)
-
Re: Ip Address Validation
Oh my God, what an expression.... How about:
Code:
public:
void fixup
(QString &input
) const {} State validate
(QString &input,
int &pos
) const { if(input.isEmpty()) return Acceptable;
int s = slist.size();
if(s>4) return Invalid;
bool emptyGroup = false;
for(int i=0;i<s;i++){
bool ok;
if(slist[i].isEmpty()){
emptyGroup = true;
continue;
}
int val = slist[i].toInt(&ok);
if(!ok || val<0 || val>255) return Invalid;
}
if(s<4 || emptyGroup) return Intermediate;
return Acceptable;
}
};
-
Re: Ip Address Validation
This worked perfectly! Thanks so much! It took me a while to get back to it, but this really did the job!
-
Re: Ip Address Validation
Quote:
Originally Posted by
Jimmy2775
I think you could do it with the combination of a masked line edit, and a QRegExpValidator that checks for a regex like this: (?:1\d?\d?|2(?:[0-4]\d?|[6789]|5[0-5]?)?|[3-9]\d?|0)(?:\.(?:1\d?\d?|2(?:[0-4]\d?|[6789]|5[0-5]?)?|[3-9]\d?|0)){3}
That said, I haven't tried this myself, so who knows... ;)
I know that problem is already solved, but... it's definetely too long regexp. I love the power of regular expressions, so here is my shorter version (w/o non-capturing parentheses, for increased readability), where each octet range from 0 to 255:
^0*(2(5[0-5]|[0-4]\d)|1?\d{1,2})(\.0*(2(5[0-5]|[0-4]\d)|1?\d{1,2})){3}$
QRegExpValidator of course doesn't need ^ and $ assertions.
-
Re: Ip Address Validation
But how to combine with setMask("000.000.000.000;")?
-
Re: Ip Address Validation
You can't. But the validator does almost the same job, especially if you implement its fixup method.
-
Re: Ip Address Validation
Hi I've the same problem...I've to implement a dialog like WinXp TCP/IP Properties of Network Connections->MyConnection Properties:
http://www.windowsnetworking.com/img...s/winrlcl1.gif
How use IP4Validator with that kind of masks (IP Address and Subnet Mask) and how to implemet them?
-
Re: Ip Address Validation
You can cheat by having four frameless line edits and three labels grouped in a horizontal layout and with overriden key events to move to the next group when the previous one is filled or when arrow keys are used. That's probably what the mentioned dialog does, too.
-
Re: Ip Address Validation
Quote:
Originally Posted by
wysota
You can cheat by having four frameless line edits and three <a href="http://www.ntsearch.com/search.php?q=labels&v=56">labels</a> grouped in a horizontal layout and with overriden key events to move to the next group when the previous one is filled or when arrow keys are used. That's probably what the mentioned dialog does, too.
Ah ok thanks...that's what I suppose!
And...about reimplementing the fixup function? what's the idea?
-
Re: Ip Address Validation
That you can change an invalid entry to a valid entry. For instance decimal point in some countries is the dot character and in others it is comma. Thanks to fixup you can detect a comma instead of a dot (or the other way round) and change it to something you consider valid.
-
Re: Ip Address Validation
Quote:
Originally Posted by
wysota
That you can change an invalid entry to a valid entry. For instance decimal point in some countries is the dot character and in others it is comma. Thanks to fixup you can detect a comma instead of a dot (or the other way round) and change it to something you consider valid.
ah ok thanks...and about fixup to format string like inputmask?
-
Re: Ip Address Validation
You can do there whatever you like.
-
Re: Ip Address Validation
can u please write the same code of urs for IP address validation.I cannt understand the code written here .
please help me out .
thanks
-
Re: Ip Address Validation
how can i use fix up in Ip address validation
-
Re: Ip Address Validation
You get an invalid address as an argument and you need to change it to a valid one, for example change all values greater than 255 to 255.
-
Re: Ip Address Validation
I realize this wins me necro-poster of the year, but I felt that this information would be beneficial to a lot of people.
The IP Address Validation (by Regex) and Mask issue was a tough cookie to crack. Setting one without the other usually worked but was flawed. I'd either not get the visual effect of having dots in the box or the user could enter invalid addresses (octets with values >255). Setting them together made it impossible to enter any value.
I found that the Class provided by Wysota solved the problem, but there was another limitation: it required you to use blanks as 0's, when I would prefer to use spaces.
Side-Note: I know a lot of people are looking for a good IP Address RegEx and here's the best one I've found so far:
Code:
\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
What I ended up doing was expanding the code that Wysota provided to allow for spaces. Here is the excerpt:
Code:
if (slist[i].isEmpty() || slist[i] == " ") {
emptyGroup = true;
continue;
}
Now that fully works with a Mask of "000.000.000.000; " and your users cannot physically enter an invalid address.
Yay! That is settled. Now for my next problem. My specific programming needs also include being able to enter in a CIDR, which has a Mask of "009.009.009.009\/09". The first part of that works just like IP Addresses and the last part is limited to integers of 0-32.
To accomplish this, I duplicated Wysota's IP Address class to CIDRValidator. Here is the full code (tested and works):
Code:
public:
void fixup
(QString &/*input*/) const { } State validate
(QString &input,
int &/*pos*/) const { if(input.isEmpty()) { return Acceptable; }
int s = slist.size();
if (s > 4) { return Invalid; }
bool emptyGroup = false;
for (int i=0; i<s; i++) {
bool ok, ok2 = true;
if (slist[i].isEmpty()
|| slist[i] == " "
|| ssplit.count() > 1 && (ssplit[0] == " " || ssplit[1] == " "))
{
emptyGroup = true;
continue;
}
int val = (ssplit.count() > 1 ? ssplit[0].toInt(&ok) : slist[i].toInt(&ok));
int cidval = (ssplit.count() > 1 ? ssplit[1].toInt(&ok2) : -1);
if((!ok || val<0 || val>255) || (ssplit.count() > 1 && (!ok2 || cidval<0 || cidval>32))) { return Invalid; }
}
if(s<4 || emptyGroup) return Intermediate;
return Acceptable;
}
};
I hope this information helps future searchers with setting up their own IP Address and CIDR Address boxes.
-
Re: Ip Address Validation
With * support class C and D
class IPV4Validator : public QValidator {
public:
IPV4Validator(QObject *parent=0) : QValidator(parent){}
State validate ( QString & input, int & pos ) const {
if(input.isEmpty()) return Intermediate;
QStringList sections = input.split(".");
if(sections.count()>4)
return Invalid;
int newPos = pos;
int grp = 0;
bool isEmpty = false;
while(grp<sections.count()){
QString txt = sections[grp];
if(txt.count()>3){
if(sections.count()==4) return Invalid;
sections[grp] = txt.left(3);
sections.insert(grp+1, txt.mid(3));
newPos++;
} else if(txt.count()==0){
isEmpty = true;
grp++;
continue;
}
txt = sections[grp];
if(txt[0]=='0' && txt[1]=='0'){
sections[grp] = '0';
if(sections.count()<4){
sections.insert(grp+1, sections[grp]);
newPos++;
}
} else if(txt[0]=='0' && txt.count()>1){
sections[grp] = txt.mid(1);
newPos--;
}
bool ok;
int val = txt.toInt(&ok);
if(!ok)
{
if(grp < 2)
return Invalid;
if(txt != "*")
return Invalid;
}
if(val>255 && sections.count()<4){
sections[grp] = txt.left(2);
sections.insert(grp+1, txt.mid(2));
val = txt.left(2).toInt();
newPos++;
}
if(val>255||val<0) return Invalid;
grp++;
}
input = sections.join(".");
// if(newPos==input.count() && sections.count()<4 && input[input.count()-1]!='.' && sections.last().count()==3){
// newPos++;
// input += ".";
// }
pos = newPos;
if(sections.count()==4 && !isEmpty) return Acceptable;
return Intermediate;
}
};
-
Re: Ip Address Validation
Hey everyone,
Thanks for all the great help.
I've written some code based on Wysota's work in the previous post. I am implementing the QValidator::fixup() to do some simple alignment and checking of integer checking (The only case when a non integer can be entered is such as "a b", this must be intermediate). The problem is that fixup gets called twice if I press <Enter> to commit the changes to the QLineEdit - displaying two error pop ups. It gets called through two separate events, a keyPressEvent and a focusOutEvent. fixup() is called the second time before it has finished running the first time.
Code:
void IP4Validator
::fixup(QString &input
) const {
bool intOk;
bool nonIntFound = false;
int s = slist.size();
for(int i=0;i<s;i++){
slist[i].toInt(&intOk);
if(!intOk){
// replace non-integers with a zero value
slist[i] = " 0";
nonIntFound = true;
}
else {
// force right align
slist[i].remove(" ");
slist[i] = slist[i].rightJustified(3,' ');
}
}
input = slist.join(".");
if(nonIntFound){
msgBox.setText("Error: The IPv4 address entered is incorrect");
msgBox.setInformativeText("At least one byte of the address was non-integer, it has now been set to 0. Please check the address");
msgBox.exec();
}
}
IP4Validator
::State IP4Validator
::validate(QString &input,
int &/*pos*/) const { if(input.isEmpty()) return Acceptable;
int s = slist.size();
if(s>4) return Invalid;
bool emptyGroup = false;
bool ok;
for(int i=0;i<s;i++){
// This cannot be true with the inputMask set, as there will be space characters
if(slist[i].isEmpty()){
emptyGroup = true;
continue;
}
int val = slist[i].toInt(&ok);
if(!ok)
return Intermediate;
else
if(val<0 || val>255)
return Invalid;
}
if(s<4 || emptyGroup) return Intermediate;
input = slist.join(".");
return Acceptable;
}
I considered accessing the type() of the event which called fixup() to filter it but I'm not sure if this is the best way to get around this. Is there something more fundamental with my logic that I have missed here?
What is the best way to handle this?
Thanks in advance for your help!
- Cotlone
-
Re: Ip Address Validation
IMO fixup() should not display any pop-ups. It should convert an invalid entry to a valid one. If you want to display a popup, you can handle focusOut()/returnPressed()/whatever, call the validator from there manually and display a popup if the validator claims the entry to be invalid.
-
Re: Ip Address Validation
I agree, actually, I was thinking that earlier today.
What do you think about fixup() emitting a signal which can be handled elsewhere? Thanks for your help.
-
Re: Ip Address Validation
Quote:
Originally Posted by
Cotlone
What do you think about fixup() emitting a signal which can be handled elsewhere?
Bad idea. You never know when fixup() might be called and if it started emitting signals in arbitrary moments, it might not be what your users expect.
-
Re: Ip Address Validation
Ok, good. It did seem a little like bad practise to me.
Looks like I'll be learning about events now then :)