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

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

#include <QLineEdit>

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 <QIntValidator>
#include <QKeyEvent>

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 <QWidget>
#include <QLabel>
#include <QResizeEvent>
#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 <QValidator>

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



  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的 Qt 自定义控件的例子,实现了一个带有渐变背景色和圆角边框的按钮: ```cpp #include <QPainter> #include <QMouseEvent> #include <QColor> class CustomButton : public QWidget { Q_OBJECT public: CustomButton(QWidget *parent = nullptr) : QWidget(parent) { setFixedSize(100, 30); setMouseTracking(true); } void setText(const QString &text) { m_text = text; update(); } QString text() const { return m_text; } protected: void paintEvent(QPaintEvent *event) override { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); // 绘制背景色 QLinearGradient gradient(0, 0, 0, height()); gradient.setColorAt(0, QColor(100, 100, 100)); gradient.setColorAt(1, QColor(150, 150, 150)); painter.setBrush(gradient); painter.drawRoundedRect(rect(), 5, 5); // 绘制文字 painter.setPen(QColor(255, 255, 255)); painter.drawText(rect().center() - QRectF(0, 0, 0, 14).center(), m_text); } void enterEvent(QEvent *event) override { // 鼠标进入控件时改变背景色 m_oldBrush = palette().brush(backgroundRole()); QLinearGradient gradient(0, 0, 0, height()); gradient.setColorAt(0, QColor(150, 150, 150)); gradient.setColorAt(1, QColor(200, 200, 200)); QBrush brush(gradient); palette().setBrush(backgroundRole(), brush); update(); } void leaveEvent(QEvent *event) override { // 鼠标离开控件时恢复背景色 palette().setBrush(backgroundRole(), m_oldBrush); update(); } void mousePressEvent(QMouseEvent *event) override { // 发射 clicked 信号 emit clicked(); } signals: void clicked(); private: QString m_text; QBrush m_oldBrush; }; ``` 在上面的代码中,我们继承了 QWidget 类,实现了自己的 paintEvent()、enterEvent()、leaveEvent() 和 mousePressEvent() 函数,分别用于绘制控件、改变背景色、恢复背景色和响应鼠标点击事件。我们还定义了一个 clicked 信号,用于通知外部程序按钮被点击了。 这个自定义控件是一个简单的按钮,但是可以通过修改代码和样式表来实现更多的功能和效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值