Qt編寫自定義IP地址控件


  在日常開發過程中,Qt給我們提供的基礎控件往往滿足不了一些復雜的開發項目,許多精巧的小控件是需要我們自己去基於一些原生控件去自定義編寫的,這也是Qt開發中的一項重要技能。比如我們在開發網絡程序的過程中,需要經常性的輸入源地址和目標地址的IP,而Qt designer並未給我們提供IP地址輸入控件(印象中MFC中有此控件),此時就需要我們自己去自定義編寫,經過本人的研究,在此貢獻一套自己編寫好的控件代碼:

MyIpPartLineEdit.h
 1 #pragma once
 2 #include <QLineEdit>   
 3 class QWidget;
 4 class QFocusEvent; 5 class QKeyEvent; 6 7 class MyIpPartLineEdit : public QLineEdit 8 { 9  Q_OBJECT 10 public: 11 MyIpPartLineEdit(QWidget *parent = 0); 12 ~MyIpPartLineEdit(void); 13 14 void set_prevtab_edit(QLineEdit *currenttab, QLineEdit *prevtab) { current_tab_ = currenttab, prev_tab_ = prevtab; } 15 void set_nexttab_edit(QLineEdit *currenttab, QLineEdit *nexttab) {current_tab_ = currenttab, next_tab_ = nexttab; } 16 17 //void 18 19 protected: 20 virtual void focusInEvent(QFocusEvent *e); 21 virtual void keyPressEvent(QKeyEvent *event); 22 23 private slots: 24 void text_edited(const QString& text); 25 26 private: 27 QLineEdit *current_tab_, *prev_tab_, *next_tab_; 28 };
MyIpPartLineEdit.cpp
#include "MyIpPartLineEdit.h"   
#include <QIntValidator>   
#include <QKeyEvent>   

MyIpPartLineEdit::MyIpPartLineEdit(QWidget *parent/* = 0*/)
	: QLineEdit(parent)
{
	next_tab_ = NULL;
	prev_tab_ = NULL;

	this->setMaxLength(3);
	this->setFrame(false);
	this->setAlignment(Qt::AlignCenter);

	QValidator *validator = new QIntValidator(0, 255, this);
	this->setValidator(validator);

	connect(this, SIGNAL(textEdited(const QString&)), this, SLOT(text_edited(const QString&)));
}

MyIpPartLineEdit::~MyIpPartLineEdit(void)
{
}

void MyIpPartLineEdit::focusInEvent(QFocusEvent *e)
{
	this->selectAll();
	QLineEdit::focusInEvent(e);
}

void MyIpPartLineEdit::keyPressEvent(QKeyEvent *event)
{
	
	if (event->key() == Qt::Key_Period)
	{
		QString current_tab = current_tab_->text();
		if (next_tab_  && (!current_tab.isEmpty()))
		{
			next_tab_->setFocus();
			next_tab_->selectAll();
		}
	}
	else if (event->key() == Qt::Key_Backspace)
	{
		QString current_tab = current_tab_->text();
		if (prev_tab_ && (current_tab.isEmpty()))
		{
			prev_tab_->setFocus();
			prev_tab_->selectAll();
		}
	}

	QLineEdit::keyPressEvent(event);
}

void MyIpPartLineEdit::text_edited(const QString& text)
{
	QIntValidator v(0, 255, this);
	QString ipaddr = text;
	int pos = 0;
	QValidator::State state = v.validate(ipaddr, pos);
	if (state == QValidator::Acceptable)
	{
		if (ipaddr.size() > 1)
		{
			if (ipaddr.size() == 2)
			{
				int ipnum = ipaddr.toInt();

				if (ipnum > 25)
				{
					if (next_tab_)
					{
						next_tab_->setFocus();
						next_tab_->selectAll();
					}
				}
			}
			else
			{
				if (next_tab_)
				{
					next_tab_->setFocus();
					next_tab_->selectAll();
				}
			}
		}
	}
}

  

MyIpAddrEdit.h
#include <QWidget>  

class QLineEdit;
class QLabel; class MyIpPartLineEdit; class MyIpAddrEdit : public QWidget { Q_OBJECT public: MyIpAddrEdit(QWidget* pParent = 0); ~MyIpAddrEdit(); void settext(const QString &text); QString text(); void getIp(QString& ip1, QString& ip2, QString& ip3, QString& ip4); void setStyleSheet(const QString &styleSheet); signals: void textchanged(const QString& text); void textedited(const QString &text); private slots: void textchangedslot(const QString& text); void texteditedslot(const QString &text); private: MyIpPartLineEdit *ip_part1_; MyIpPartLineEdit *ip_part2_; MyIpPartLineEdit *ip_part3_; //QLineEdit *ip_part4_; MyIpPartLineEdit *ip_part4_; QLabel *labeldot1_; QLabel *labeldot2_; QLabel *labeldot3_; };
MyIpAddrEdit.cpp
#include "MyIpAddrEdit.h"   
#include <QRegExpValidator>   
#include <QLabel>   
#include "MyIpPartLineEdit.h"
#include "qjsondocument.h"


MyIpAddrEdit::MyIpAddrEdit(QWidget* pParent /* = 0 */)
	: QWidget(pParent)
{
	QFont font(".萍方-簡", 10);
	ip_part1_ = new MyIpPartLineEdit(this);
	ip_part2_ = new MyIpPartLineEdit(this);
	ip_part3_ = new MyIpPartLineEdit(this);
	ip_part4_ = new MyIpPartLineEdit(this);

	labeldot1_ = new QLabel(this);
	labeldot2_ = new QLabel(this);
	labeldot3_ = new QLabel(this);

	ip_part1_->setGeometry(QRect(0,  0, 44, 28));
	ip_part2_->setGeometry(QRect(44, 0, 44, 28));
	ip_part3_->setGeometry(QRect(88, 0, 44, 28));
	ip_part4_->setGeometry(QRect(132,0, 44, 28));

	ip_part1_->setFont(font);
	ip_part2_->setFont(font);
	ip_part3_->setFont(font);
	ip_part4_->setFont(font);

	labeldot1_->setText(" .");
	labeldot1_->setFont(font);
	labeldot1_->setGeometry(QRect(41, 5, 6, 18));
	labeldot1_->setAlignment(Qt::AlignCenter);

	labeldot2_->setText(" .");
	labeldot2_->setFont(font);
	labeldot2_->setGeometry(QRect(85, 5, 6, 18));
	labeldot2_->setAlignment(Qt::AlignCenter);

	labeldot3_->setText(" .");
	labeldot3_->setFont(font);
	labeldot3_->setGeometry(QRect(129, 5, 6, 18));
	labeldot3_->setAlignment(Qt::AlignCenter);

	QWidget::setTabOrder(ip_part1_, ip_part2_);//定義切換焦點順序
	QWidget::setTabOrder(ip_part2_, ip_part3_);
	QWidget::setTabOrder(ip_part3_, ip_part4_);

	ip_part1_->set_nexttab_edit(ip_part1_, ip_part2_);
	ip_part2_->set_nexttab_edit(ip_part2_, ip_part3_);
	ip_part3_->set_nexttab_edit(ip_part3_, ip_part4_);
	
	ip_part2_->set_prevtab_edit(ip_part2_, ip_part1_);
	ip_part3_->set_prevtab_edit(ip_part3_, ip_part2_);
	ip_part4_->set_prevtab_edit(ip_part4_, ip_part3_);

	connect(ip_part1_, SIGNAL(textChanged(const QString&)), this, SLOT(textchangedslot(const QString&)));
	connect(ip_part2_, SIGNAL(textChanged(const QString&)), this, SLOT(textchangedslot(const QString&)));
	connect(ip_part3_, SIGNAL(textChanged(const QString&)), this, SLOT(textchangedslot(const QString&)));
	connect(ip_part4_, SIGNAL(textChanged(const QString&)), this, SLOT(textchangedslot(const QString&)));

	connect(ip_part1_, SIGNAL(textEdited(const QString&)), this, SLOT(texteditedslot(const QString&)));
	connect(ip_part2_, SIGNAL(textEdited(const QString&)), this, SLOT(texteditedslot(const QString&)));
	connect(ip_part3_, SIGNAL(textEdited(const QString&)), this, SLOT(texteditedslot(const QString&)));
	connect(ip_part4_, SIGNAL(textEdited(const QString&)), this, SLOT(texteditedslot(const QString&)));

}

MyIpAddrEdit::~MyIpAddrEdit()
{

}

void MyIpAddrEdit::textchangedslot(const QString& /*text*/)
{
	QString ippart1, ippart2, ippart3, ippart4;
	ippart1 = ip_part1_->text();
	ippart2 = ip_part2_->text();
	ippart3 = ip_part3_->text();
	ippart4 = ip_part4_->text();

	QString ipaddr = QString("%1.%2.%3.%4")
		.arg(ippart1)
		.arg(ippart2)
		.arg(ippart3)
		.arg(ippart4);

	emit textchanged(ipaddr);
}

void MyIpAddrEdit::texteditedslot(const QString &/*text*/)
{
	QString ippart1, ippart2, ippart3, ippart4;
	ippart1 = ip_part1_->text();
	ippart2 = ip_part2_->text();
	ippart3 = ip_part3_->text();
	ippart4 = ip_part4_->text();

	QString ipaddr = QString("%1.%2.%3.%4")
		.arg(ippart1)
		.arg(ippart2)
		.arg(ippart3)
		.arg(ippart4);

	emit textedited(ipaddr);
}

void MyIpAddrEdit::settext(const QString &text)
{
	QString ippart1, ippart2, ippart3, ippart4;
	QString qstring_validate = text;

	// IP地址驗證   
	QRegExp regexp("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)");
	QRegExpValidator regexp_validator(regexp, this);
	int nPos = 0;
	QValidator::State state = regexp_validator.validate(qstring_validate, nPos);
	// IP合法   
	if (state == QValidator::Acceptable)
	{
		QStringList ippartlist = text.split(".");

		int strcount = ippartlist.size();
		int index = 0;
		if (index < strcount)
		{
			ippart1 = ippartlist.at(index);
		}
		if (++index < strcount)
		{
			ippart2 = ippartlist.at(index);
		}
		if (++index < strcount)
		{
			ippart3 = ippartlist.at(index);
		}
		if (++index < strcount)
		{
			ippart4 = ippartlist.at(index);
		}
	}

	ip_part1_->setText(ippart1);
	ip_part2_->setText(ippart2);
	ip_part3_->setText(ippart3);
	ip_part4_->setText(ippart4);
}

QString MyIpAddrEdit::text()
{
	QString ippart1, ippart2, ippart3, ippart4;
	ippart1 = ip_part1_->text();
	ippart2 = ip_part2_->text();
	ippart3 = ip_part3_->text();
	ippart4 = ip_part4_->text();

	return QString("%1.%2.%3.%4")
		.arg(ippart1)
		.arg(ippart2)
		.arg(ippart3)
		.arg(ippart4);
}

void MyIpAddrEdit::getIp(QString& ip1, QString& ip2, QString& ip3, QString& ip4)
{
	ip1 = ip_part1_->text();
	ip2 = ip_part2_->text();
	ip3 = ip_part3_->text();
	ip4 = ip_part4_->text();
}


void MyIpAddrEdit::setStyleSheet(const QString &styleSheet)
{
	ip_part1_->setStyleSheet(styleSheet);
	ip_part2_->setStyleSheet(styleSheet);
	ip_part3_->setStyleSheet(styleSheet);
	ip_part4_->setStyleSheet(styleSheet);
}

 

在工程中添加上述C++文件后,便可以使用,使用方法如下:

在工程類頭文件中聲明 IP 地址類 成員變量:


在使用前對其進行初始化(一般在項目構造函數中):
此處在下是直接將其添加進入一個水平布局中,大家使用的時候可以隨意。

方法調用:
m_objIpAddrEdit->settext(p_ip);     //設置IP地址(也可以手動輸入)
QString p_ip = m_objIpAddrEdit->text();    //獲取IP地址
QString p_ip1, p_ip2, p_ip3, p_ip4, p_ip;  
m_objIpAddrEdit->getIp(p_ip1, p_ip2, p_ip3, p_ip4); //獲取IP地址的四個部分
//判斷IP輸入是否合法
 if (p_ip1 == NULL || p_ip2 == NULL || p_ip3 == NULL || p_ip4 == NULL)
{
	strMessage = tr("IP settings are illegal, please reenter it!\n");
	qBox.setText(strMessage);
	switch (qBox.exec())
	{
	case QMessageBox::Yes:
		{
			return;
		}
	}
}   

運行效果:

ok,我想我說的已經很明了了,希望能夠幫助到各位。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM