输入IP地址是一个很常用的功能,但QT并没有相对应的控件,我只好自己写一个了(类似于MFC的CIPAddressCtrl)。
主要思路:
1:建立4个QSpinBox输入框和3个QLabel,并排列好。4:如果某个输入框得到了输入焦点,则将它们设为全选状态;如果输入框内的字符为0,则清空该输入框(防止用户输入多个0);如果输入框内的数字大于25,则输入焦点自动跳到下一格。
截图:
源代码:
#include <QtGui> //IP地址输入框 class IpAddressWidget : public QWidget { Q_OBJECT private: QSpinBox *m_SpinBox[4]; QLabel *m_Label[3]; QString m_Separator; //四个数字之间的分隔符 protected: bool eventFilter(QObject *object, QEvent *event); public: IpAddressWidget(QWidget *parent = 0); ~IpAddressWidget(); QString GetIpAddressString(); void SetSeparator(const QString &separator); }; //测试例子 class TestWidget : public QWidget { Q_OBJECT private: IpAddressWidget *ipAddressWidget; QPushButton *OKButton; public: TestWidget(QWidget *parent = 0); ~TestWidget(); public slots: void ClickedOKButton(); }; IpAddressWidget::IpAddressWidget(QWidget *parent /* = 0 */) { m_Separator = " : "; //四个数字的输入框,QSpinBox实现,范围是0~255,无“上下按钮”,文字居中 //这里也可以用QLineEdit+QIntValidator实现,但个人觉得这种方法不好用 for(int i=0; i<4; i++) { m_SpinBox[i] = new QSpinBox(this); m_SpinBox[i]->setRange(0, 255); m_SpinBox[i]->setButtonSymbols(QAbstractSpinBox::NoButtons); m_SpinBox[i]->setAlignment(Qt::AlignCenter); m_SpinBox[i]->setFixedWidth(40); m_SpinBox[i]->installEventFilter(this); } //四个输入框之间的分隔符 for(int i=0; i<3; i++) { m_Label[i] = new QLabel(m_Separator, this); m_Label[i]->setFixedWidth(10); m_Label[i]->setAlignment(Qt::AlignCenter); } QHBoxLayout *layout = new QHBoxLayout; layout->setSpacing(0); for(int i=0; i<3; i++) { layout->addWidget(m_SpinBox[i]); layout->addWidget(m_Label[i]); } layout->addWidget(m_SpinBox[3]); setLayout(layout); } IpAddressWidget::~IpAddressWidget() { } //获取IP地址,如果该地址不合法,则返回空字符串 QString IpAddressWidget::GetIpAddressString() { QString ipAddress; for(int i=0; i<3; i++) { if( m_SpinBox[i]->text().isEmpty() ) { ipAddress.clear(); return ipAddress; } ipAddress += m_SpinBox[i]->text() + m_Separator; } ipAddress += m_SpinBox[3]->text(); return ipAddress; } bool IpAddressWidget::eventFilter(QObject *object, QEvent *event) { //如果object不是四个输入框,则返回 int nowBox = -1; for(int i=0; i<4; i++) { if( object == m_SpinBox[i] ) nowBox = i; } if( -1 == nowBox ) return false; QSpinBox *spinBox = dynamic_cast<QSpinBox*>(object); //如果某个输入框得到了输入焦点,则将它们设为全选状态 if( QEvent::FocusIn == event->type() ) { spinBox->selectAll(); return true; } //如果输入框内的字符为0,则清空该输入框(防止用户输入多个0) else if( QEvent::KeyPress == event->type() ) { QString context = spinBox->text(); if( "0" == context ) spinBox->clear(); } //如果输入框内的数字大于25,则输入焦点自动跳到下一格 else if( QEvent::KeyRelease == event->type() ) { int val = spinBox->value(); if( spinBox->value() > 25 && nowBox < 3 ) { m_SpinBox[nowBox+1]->setFocus(); } } return false; } TestWidget::TestWidget(QWidget *parent /* = 0 */) { ipAddressWidget = new IpAddressWidget(this); OKButton = new QPushButton(tr("OK"), this); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(ipAddressWidget); layout->addWidget(OKButton); setLayout(layout); connect(OKButton, SIGNAL(clicked()), this, SLOT(ClickedOKButton())); setWindowTitle("IP Address Widget"); } TestWidget::~TestWidget() { } void TestWidget::ClickedOKButton() { QString ipAddress = ipAddressWidget->GetIpAddressString(); if( ipAddress.isEmpty() ) QMessageBox::information( this, tr("Error"), tr("The IP address is illegal") ); else QMessageBox::information(this, tr("IP Address"), ipAddress); } #include "main.moc" int main(int argc, char *argv[]) { QApplication app(argc, argv); TestWidget *widget = new TestWidget; widget->show(); return app.exec(); }