自定义多选QComboBox

因项目需求,要实现QComboBox的多选功能。思路是采用QListWidget、QListWidgetItem和QCheckBox。具体实现时,先在Qt designer的UI添加QComboBox控件并提升为自定义控件MutiComboBox,再通过setModelData方式将列表数据传给MutiComboBox。

因项目需求,需要实现QComboBox的多选功能,如下图所示:

思路:QListWidget + QListWidgetItem + QCheckBox

代码如下

#ifndef MUTICOMBOBOX_H
#define MUTICOMBOBOX_H

#include <QWidget>
#include <QListWidget>
#include <QLineEdit>
#include <QComboBox>


class  MutiComboBox : public QComboBox
{
	Q_OBJECT

public:
	MutiComboBox(QWidget *parent = 0);
	MutiComboBox(const QMap<int,QString> &mapData,QWidget *parent = 0);
	~MutiComboBox();

public:
	void setModelData(const QMap<int,QString> &mapData);
	void setCheckedItems(const QString &data);
	QString getSelectedItemDatas();


private slots:
	void stateChanged(int state);
	void textChanged(const QString &text);

private:
	void clear();

private:
	QListWidget *pListWidget;
	QLineEdit *pLineEdit;
	QString strSelectedText;
	bool bSelected;
};

#endif // MUTICOMBOBOX_H

具体实现:

#include "muticombobox.h"

#include <QCheckBox>
#include <QDebug>


MutiComboBox::MutiComboBox(QWidget *parent)
	: QComboBox(parent)
{
	pListWidget = new QListWidget(this);
	pListWidget->setObjectName("MutiComboBoxListWidget");
	pLineEdit = new QLineEdit(this);
	//this->setModel(pListWidget->model());
	//this->setView(pListWidget);
	this->setLineEdit(pLineEdit);
	pLineEdit->setReadOnly(true);
	connect(pLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(textChanged(const QString &)));
}

MutiComboBox::MutiComboBox(const QMap<int,QString> &mapData,QWidget *parent)
:QComboBox(parent)
{
	pListWidget = new QListWidget(this);
	pLineEdit = new QLineEdit(this);
	QMapIterator<int,QString> it(mapData);
	while(it.hasNext()){
		it.next();
		QListWidgetItem *pItem = new QListWidgetItem(pListWidget);
		pListWidget->addItem(pItem);
		pItem->setData(Qt::UserRole,it.key());
		QCheckBox *pCheckBox = new QCheckBox(this);
		pCheckBox->setText(it.value());
		pListWidget->addItem(pItem);
		pListWidget->setItemWidget(pItem,pCheckBox);
		connect(pCheckBox,SIGNAL(stateChanged(int)),this,SLOT(stateChanged(int)));
	}

	this->setModel(pListWidget->model());
	this->setView(pListWidget);
	this->setLineEdit(pLineEdit);
	pLineEdit->setReadOnly(true);
	connect(pLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(textChanged(const QString &)));
}

MutiComboBox::~MutiComboBox()
{
	delete pListWidget;
	delete pLineEdit;
}
void MutiComboBox::setModelData(const QMap<int,QString> &mapData)
{
	int count = pListWidget->count();
	for (int row = 0; row < count;++row)
	{
		QListWidgetItem *pItem = pListWidget->takeItem(0);
		delete pItem;
	}
	
	QMapIterator<int,QString> it(mapData);
	while(it.hasNext()){
		it.next();
		QListWidgetItem *pItem = new QListWidgetItem(pListWidget);
		pListWidget->addItem(pItem);
		pItem->setData(Qt::UserRole,it.key());
		QCheckBox *pCheckBox = new QCheckBox(this);
		pCheckBox->setText(it.value());
		pListWidget->addItem(pItem);
		pListWidget->setItemWidget(pItem,pCheckBox);
		connect(pCheckBox,SIGNAL(stateChanged(int)),this,SLOT(stateChanged(int)));
	}
	this->setModel(pListWidget->model());
	this->setView(pListWidget);
}

void MutiComboBox::setCheckedItems(const QString &data)
{
	clear();

	if(data.isEmpty())
		return;

	int count = pListWidget->count();
	QStringList list(data.split(";"));
	QStringListIterator it(list);
	while(it.hasNext())
	{
		QString da = it.next();
		for(int i=0;i<count;++i)
		{
			QListWidgetItem *pItem = pListWidget->item(i);
			if(pItem->data(Qt::UserRole).toString() == da)
			{
				QWidget *pWidget = pListWidget->itemWidget(pItem);
				QCheckBox *pCheckBox = (QCheckBox*) pWidget;
				pCheckBox->setChecked(true);
				break;
			}
		}
	}
}
QString MutiComboBox::getSelectedItemDatas()
{
	int nCount = pListWidget->count();
	QString strSeltectedData("");
	for(int i=0; i < nCount; ++i)
	{
		QListWidgetItem *pItem = pListWidget->item(i);
		QWidget *pWidget = pListWidget->itemWidget(pItem);
		QCheckBox *pCheckBox = (QCheckBox*) pWidget;
		if(pCheckBox->isChecked()){
			QString strText = pItem->data(Qt::UserRole).toString().trimmed();
			strSeltectedData.append(strText).append(";");
		}
	}

	if(strSeltectedData.endsWith(";"))
	{
		strSeltectedData.remove(strSeltectedData.count()-1,1);
	}
	return strSeltectedData;
}


void MutiComboBox::stateChanged(int state)
{
	bSelected = true;
	QString strSelectedData("");
	strSelectedText.clear();
	QObject *object= QObject::sender();
	QCheckBox *pSenderCheckBox = static_cast<QCheckBox*>(object);
	int nCount = pListWidget->count();
	for(int i=0; i < nCount; ++i)
	{
		QListWidgetItem *pItem = pListWidget->item(i);
		QWidget *pWidget = pListWidget->itemWidget(pItem);
		QCheckBox *pCheckBox = (QCheckBox*) pWidget;
		if(pCheckBox->isChecked()){
			QString strText = pCheckBox->text();
			strSelectedData.append(strText).append(";");
		}
	}

	if(strSelectedData.endsWith(";"))
	{
		strSelectedData.remove(strSelectedData.count()-1,1);
	}

	if(!strSelectedData.isEmpty())
	{
		strSelectedText = strSelectedData;
		pLineEdit->setText(strSelectedData);
		pLineEdit->setToolTip(strSelectedData);
	}else{
		pLineEdit->clear();
	}
	bSelected = false;
}

void MutiComboBox::textChanged(const QString &text)
{
	if(!bSelected)
	{
		pLineEdit->setText(strSelectedText);
	}
}

void MutiComboBox::clear(){
	int nCount = pListWidget->count();
	for(int i=0; i < nCount; ++i)
	{
		QListWidgetItem *pItem = pListWidget->item(i);
		QWidget *pWidget = pListWidget->itemWidget(pItem);
		QCheckBox *pCheckBox = (QCheckBox*) pWidget;
		if(pCheckBox->isChecked()){
			pCheckBox->setChecked(false);
		}
	}
	strSelectedText = "";
	pLineEdit->setText("");
}

使用方法:

1.在Qt designer中的UI先添加 QComboBox控件,然后提升该控件为自定义的控件 MutiComboBox

2.通过setModelData的方式,将列表中的数据传给MutiComboBox

如:

    ui->cmbRes->setModelData(m_LogictActIDMap);

 

评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值