QT 实现自定义的IP地址控件

此IP输入控件支持可通过tab,值大于255,点击.按钮,或者左右键切换等来实现切换输入框。
单个输入框功能,限制大小0-255;
#ifndef CMYIPPARTLINEEDIT_H
#define CMYIPPARTLINEEDIT_H

#include 

class CMyIpPartLineEdit : public QLineEdit
{
	Q_OBJECT

public:
	CMyIpPartLineEdit(QWidget *parent = 0,int nType = 0);
	~CMyIpPartLineEdit();

	void set_nexttab_edit(QLineEdit *nexttab) { next_tab_ = nexttab; }
	void setEditCursorPosition(int nType);
public:signals:
	void keyPressLeftOrRight(int,int);

protected:
	virtual void focusInEvent(QFocusEvent *e);
	virtual void keyPressEvent(QKeyEvent *event);  

private slots:
	void text_edited(const QString& text);

private:
	QLineEdit *next_tab_;
	int m_nType;
};

#endif // CMYIPPARTLINEEDIT_H



#include "CMyIpPartLineEdit.h"

#include 
#include 

CMyIpPartLineEdit::CMyIpPartLineEdit(QWidget *parent/* = 0*/,int nType)
: QLineEdit(parent)
{
	next_tab_ = NULL;
 
	this->setMaxLength(3);
	this->setFrame(false);
	this->setAlignment(Qt::AlignCenter);

	QValidator *validator = new QIntValidator(0, 255, this);
	this->setValidator(validator);
	switch(nType)
	{
	case 0:
		//第一个
		setStyleSheet("QLineEdit{border-right:0px;}");
		break;
	case 1:
		//第二个
		setStyleSheet("QLineEdit{border-left:0px;border-right:0px;}");
		break;
	case 2:
		//第三个
		setStyleSheet("QLineEdit{border-left:0px;border-right:0px;}");
		break;
	case 3:
		setStyleSheet("QLineEdit{border-left:0px;}");
		break;
	}
	m_nType = nType;

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

CMyIpPartLineEdit::~CMyIpPartLineEdit(void)
{
}

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

void CMyIpPartLineEdit::keyPressEvent(QKeyEvent *event)
{
	if (event->key() == Qt::Key_Period)
	{
		if (next_tab_)
		{
			next_tab_->setFocus();
			next_tab_->selectAll();
		}
	}
	else if (event->key() == Qt::Key_Left)
	{
		if (cursorPosition() == 0&&m_nType!=0)
		{
			emit keyPressLeftOrRight((int)Qt::Key_Left,m_nType-1);
		}
	}
	else if (event->key() == Qt::Key_Right)
	{
		if (cursorPosition() == text().size()&&m_nType!=3)
		{
			emit keyPressLeftOrRight((int)Qt::Key_Right,m_nType+1);
		}
	}
	QLineEdit::keyPressEvent(event);
}

void CMyIpPartLineEdit::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();
				}    
			}
		}
	}
}


void CMyIpPartLineEdit::setEditCursorPosition(int nType)
{
	setFocus();
	int nSize = 0;
	if (nType == Qt::Key_Left)
	{
		nSize = text().size();
	}
	setCursorPosition(nSize);
}


整个IP控件实现,已经样式表实现控件样式。实现随设置大小自适应,建议大于80。实现左右按钮切换。

#ifndef CMYIPADDREDIT_H
#define CMYIPADDREDIT_H

#include 
#include 
#include 
#include "cmyippartlineedit.h"

class CMyIpAddrEdit : public QWidget
{
	Q_OBJECT

public:
	CMyIpAddrEdit(QWidget *parent = 0);
	~CMyIpAddrEdit();

	void setText(const QString &text);
	QString text();
	void setStyleSheet(const QString &styleSheet);
	void setEnabled(bool);
signals:
	void textchanged(const QString& text);
	void textedited(const QString &text);

public slots:
	void onKeyPressLeftOrRight(int,int);
protected:
	void resizeEvent(QResizeEvent* event);

private slots:
	void textchangedslot(const QString& text);
	void texteditedslot(const QString &text);

private:
	CMyIpPartLineEdit *ip_part1_;
	CMyIpPartLineEdit *ip_part2_;
	CMyIpPartLineEdit *ip_part3_;
	CMyIpPartLineEdit *ip_part4_;

	QLabel *labeldot1_;
	QLabel *labeldot2_;    
	QLabel *labeldot3_;
};

#endif // CMYIPADDREDIT_H




#include "cmyipaddredit.h"
#include 

CMyIpAddrEdit::CMyIpAddrEdit(QWidget *parent)
	: QWidget(parent)
{
	ip_part1_ = new CMyIpPartLineEdit(this,0);
	ip_part2_ = new CMyIpPartLineEdit(this,1);
	ip_part3_ = new CMyIpPartLineEdit(this,2);
	ip_part4_ = new CMyIpPartLineEdit(this,3);

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

	labeldot1_->setText(" .");
	labeldot1_->setAlignment(Qt::AlignCenter);

	labeldot2_->setText(" .");
	labeldot2_->setAlignment(Qt::AlignCenter);

	labeldot3_->setText(" .");
	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_part2_);
	ip_part2_->set_nexttab_edit(ip_part3_);
	ip_part3_->set_nexttab_edit(ip_part4_);


	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&)));

	connect(ip_part1_, SIGNAL(keyPressLeftOrRight(int,int)), this, SLOT(onKeyPressLeftOrRight(int,int)));
	connect(ip_part2_, SIGNAL(keyPressLeftOrRight(int,int)), this, SLOT(onKeyPressLeftOrRight(int,int)));
	connect(ip_part3_, SIGNAL(keyPressLeftOrRight(int,int)), this, SLOT(onKeyPressLeftOrRight(int,int)));
	connect(ip_part4_, SIGNAL(keyPressLeftOrRight(int,int)), this, SLOT(onKeyPressLeftOrRight(int,int)));
}

CMyIpAddrEdit::~CMyIpAddrEdit()
{

}

void CMyIpAddrEdit::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 CMyIpAddrEdit::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 CMyIpAddrEdit::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 CMyIpAddrEdit::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 CMyIpAddrEdit::setStyleSheet(const QString &styleSheet)
{
	ip_part1_->setStyleSheet(styleSheet);
	ip_part2_->setStyleSheet(styleSheet);
	ip_part3_->setStyleSheet(styleSheet);
	ip_part4_->setStyleSheet(styleSheet);
}

void CMyIpAddrEdit::onKeyPressLeftOrRight(int nkeyType,int nNewLineEditType)
{
	switch(nNewLineEditType)
	{
	case 0:
		ip_part1_->setEditCursorPosition(nkeyType);
		break;
	case 1:
		ip_part2_->setEditCursorPosition(nkeyType);
		break;
	case 2:
		ip_part3_->setEditCursorPosition(nkeyType);
		break;
	case 3:
		ip_part4_->setEditCursorPosition(nkeyType);
		break;
	}
}

void CMyIpAddrEdit::setEnabled(bool bEnable)
{
	ip_part1_->setEnabled(bEnable);
	ip_part2_->setEnabled(bEnable);
	ip_part3_->setEnabled(bEnable);
	ip_part4_->setEnabled(bEnable);

	labeldot1_->setEnabled(bEnable);
	labeldot2_->setEnabled(bEnable);
	labeldot3_->setEnabled(bEnable);
}

void CMyIpAddrEdit::resizeEvent(QResizeEvent* event)
{
	int nWidth = width()/4;
	int nHeight = height();
	ip_part1_->setGeometry(QRect(0, 0, nWidth, nHeight));
	ip_part2_->setGeometry(QRect(nWidth, 0, nWidth, nHeight));
	ip_part3_->setGeometry(QRect(nWidth*2, 0, nWidth, nHeight));
	ip_part4_->setGeometry(QRect(nWidth*3, 0, width()-nWidth*3, nHeight));

	labeldot1_->setGeometry(QRect(nWidth-3, 1, 6, nHeight-2));
	labeldot2_->setGeometry(QRect(nWidth*2-3, 1, 6, nHeight-2));
	labeldot3_->setGeometry(QRect(nWidth*3-3, 1, 6, nHeight-2));
}



你可能感兴趣的:(QT,知识应用)