在Qt 6.8.1 (MSVC 2022, x86_64)中进行编写,需要实现IP和端口号输入的弹窗,实现的方式有2种,其一,采用UI绘制,然后进行界面加载实现;其二,采用对话框dialog实现。考虑到采用UI实现,在主界面基础上,在加载新页面,会有2个页面,效果不佳,因此主要考虑采用第二种方式。在本博文中,主要对该类的使用进行封装,方便后续可以直接使用。
在编写过程中,主要是对于QDialog的基本使用,其中需要实现一个效果:当输入信息是有效的,才能使用点击按钮,否则无法点击操作。基于这个需求,主要采用对输入框的信号监测实现,查看QLineEdit类,使用的信号如下:
其中重点关注textChanged(const QString &)
和textEdited(const QString &)
,两者都是会根据文字变更进行相对于的信号触发,只是textEdited特指由用户主动编辑(如键盘输入、删除、粘贴)引起的文本变化,通常不包括代码直接修改文本的情况(如textView.setText("new text")
);textChanged则是无论变化是由用户输入、程序代码修改,还是其他外部因素引起的,都会触发。在本博文中,根据需求研究,主要采用textEdited实现。
connect(ipLineEdit,&QLineEdit::textEdited,this,&UnionWidget::lineEdit);
connect(portLineEdit,&QLineEdit::textEdited,this,&UnionWidget::lineEdit);
有效的端口号应该在0-65535有效范围内;合法IPv4应该是4段,且每段0-255。因此IP正则规则如下:
QRegularExpression ipv4Regex(
R"(^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)"
R"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)"
R"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)"
R"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$)"
);
对该规则进行解释:
25[0-5]
:匹配 250-255,以25开头,第三位是0-5。2[0-4][0-9]
:匹配 200-249,以2开头,第二位是0-4,第三位是0-9。[01]?[0-9][0-9]?
:匹配 0-199,[01]?
可选的0或1(表示 100-199),[0-9]
必须有一个数字(0-9),[0-9]?
可选的第二个数字(用于两位数,如 10-99)。基于以上分析,首先,实现界面展示:
QDialog dialog(this);
dialog.setWindowFlag(Qt::FramelessWindowHint,true);
QFormLayout form(&dialog);
form.addRow(new QLabel("请输入FLS的ip和端口:"));
QLineEdit* ipLineEdit =new QLineEdit(&dialog);
QLineEdit* portLineEdit =new QLineEdit(&dialog);
form.addRow("IP:", ipLineEdit);
form.addRow("PORT:", portLineEdit);
QDialogButtonBox *buttonBox=new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
Qt::Horizontal, &dialog);
QPushButton *okButton =buttonBox->button(QDialogButtonBox::Ok);
okButton->setEnabled(false);
form.addRow(buttonBox);
connect(buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
connect(ipLineEdit,&QLineEdit::textEdited,this,&UnionWidget::lineEdit);
connect(portLineEdit,&QLineEdit::textEdited,this,&UnionWidget::lineEdit);
if(dialog.exec() ==QDialog::Accepted){
//同意后逻辑
}
其次,进行槽函数实现,要注意这里的ip和port 是全局变量:
private:
QString ip;
QString port;
void UnionWidget::lineEdit(const QString &)
{
ip =ipLineEdit->text();
port =portLineEdit->text();
HttpAPI http;
if(!ip.isEmpty() && !port.isEmpty() && http.isValid(ip,port.toInt())){
okButton->setEnabled(true);
}else{
okButton->setEnabled(false);
}
}
最后,进行合法性判断:
bool HttpAPI::isValid(const QString &ip, const int &port)
{
QRegularExpression ipv4Regex(
R"(^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)"
R"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)"
R"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)"
R"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$)"
);
return ((port >= 0 && port <= 65535) && ipv4Regex.match(ip).hasMatch());
}