qt QListView下拉多选框

在这里插入图片描述
XComboBox.h

#pragma once

#include <QComboBox>
#include <QStandardItemModel>
#include <QListView>
#include <QKeyEvent>

#include "commonplugin_global.h"
#include <QCompleter>

class QLineEdit;
class QListView;

struct ItemInfo
{
	int idx;
	QString str;
	QVariant userData;
	bool bChecked;

	ItemInfo()
	{
		idx = -1;
		str = QString::fromLocal8Bit("");
		userData = QVariant();
		bChecked = false;
	}
};

class  XListView : public QListView
{
	Q_OBJECT
public:
	XListView(QWidget* parent= Q_NULLPTR):QListView(parent)
	{
	}
	~XListView()
	{
	}
protected:
	void keyPressEvent(QKeyEvent *e)
	{
		e->accept();
	}
};

class KeyPressEater :public QObject
{
	Q_OBJECT
public:
	KeyPressEater(QObject* parent = nullptr) :QObject(parent)
	{

	}
	~KeyPressEater()
	{

	}
signals:
	void sigActivated(int idx);

protected:
	bool eventFilter(QObject *obj, QEvent *event)
	{
		if (event->type() == QEvent::KeyPress)
		{
			QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
			if (keyEvent->key() == Qt::Key_Space)
			{
				QListView* lstV = qobject_cast<QListView*>(obj);
				if (nullptr != lstV)
				{
					int idx = lstV->currentIndex().row();
					if (-1 != idx)
					{
						emit sigActivated(idx);
					}
				}
			}
			else if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down)
			{
				return QObject::eventFilter(obj, event);
			}
			return true;
		}
		else 
		{
			return QObject::eventFilter(obj, event);
		}
	}
};

class XComboBox : public QComboBox
{
	Q_OBJECT
public:
	XComboBox(QWidget *parent = Q_NULLPTR);
	~XComboBox();

	//添加item
    void AddItem(const QString& str, bool bChecked = false,  const QVariant &userData = QVariant());
	void AddItems(const QList<ItemInfo>& lstItemInfo);
	void AddItems(const QMap<QString, bool>& mapStrChk);
	void AddItems(const QList<QString>& lstStr);
	void AddItems(const QStringList& lstStr, QList<int> trueIndex);//by lxf
	void AddItemContent(const QStringList& lstStr, QStringList currentStr = {});
	// 删除item
	void RemoveItem(int idx);
	// 清空item
	void Clear();
	// 获取选中的数据字符串列表
	QStringList GetSelItemsText();
	// 获取选中item的信息
	QList<ItemInfo> GetSelItemsInfo();
	// 获取item文本
	QString GetItemText(int idx);
	// 获取item信息
	ItemInfo GetItemInfo(int idx);

	void setChecked(int index);//设置勾选状态

	void iniCompleter(QStringList lineList);//模糊搜索

signals:
	// popup显示信号
	void showingPopup();
	// popup隐藏信号
	void hidingPopup();

protected:
	void showPopup();
	// 重写QComboBox的hidePopup函数
	// 目的选择过程中,不隐藏listview
	void hidePopup();
	virtual void mousePressEvent(QMouseEvent * event);
	virtual void mouseReleaseEvent(QMouseEvent * event);
	virtual void mouseMoveEvent(QMouseEvent * event);
private:
	void UpdateText();

private slots:
	void sltActivated(int idx);

private:
	QLineEdit* pLineEdit;
	QListView* pListView;
	QStandardItemModel m_model;
public:
	QCompleter * completer;
};

XComboBox.cpp

#include "XComboBox.h"
#include <QLineEdit>
#include <QMouseEvent>

XComboBox::XComboBox(QWidget *parent /* = Q_NULLPTR */)
	:QComboBox(parent)
{
	pLineEdit = new QLineEdit(this);
	pLineEdit->setFont(QFont(QString::fromLocal8Bit(" 微软雅黑 "), 12));
	//pLineEdit->setReadOnly(true);
	this->setLineEdit(pLineEdit);
	this->lineEdit()->disconnect();

	KeyPressEater * keyPressEater = new KeyPressEater(this);
	pListView = new QListView(this);
	pListView->installEventFilter(keyPressEater);
	this->setView(pListView);
	this->setModel(&m_model);

	connect(this, SIGNAL(activated(int)), this, SLOT(sltActivated(int)));
	connect(keyPressEater, SIGNAL(sigActivated(int)), this, SLOT(sltActivated(int)));
}

XComboBox::~XComboBox()
{

}
void XComboBox::iniCompleter(QStringList lineList)
{
	/* 新建一个公用的completer */
	completer = new QCompleter(lineList, this);
	/* CaseInsensitive不区分大小写/CaseSensitive区分大小写 */
	completer->setCaseSensitivity(Qt::CaseInsensitive);
	/* PopupCompletion符合值弹出一个窗口
	* InlineCompletion符合值会直接内嵌到文本输入框中
	* UnfilteredPopupCompletion所有的筛选条件都列出,符合条件的在最前
	*/
	completer->setCompletionMode(QCompleter::PopupCompletion);
	/* 最大显示符合条件的个数 */
	completer->setMaxVisibleItems(10);
	//    /* 补全路径 */
	//    QFileSystemModel *model = new QFileSystemModel;
	//    model->setRootPath(QDir::currentPath());
	//    completer->setModel(model);
	//    /* 日期,时间,ip,等等一大堆 */
	pLineEdit->setCompleter(completer);
}

void XComboBox::AddItem(const QString& str, bool bChecked /* = false */, const QVariant &userData /* = QVariant() */ )
{
    QStandardItem* item = new QStandardItem(str);
    item->setCheckable(true);
    item->setCheckState(bChecked ? Qt::Checked : Qt::Unchecked);
    item->setData(userData, Qt::UserRole + 1);
    //item->setCheckState(Qt::Checked);//by lxf
    m_model.appendRow(item);
    UpdateText();
}
void XComboBox::setChecked(int index)
{

}

void XComboBox::AddItems(const QMap<QString, bool>& mapStrChk)
{
	for (auto it = mapStrChk.begin(); it != mapStrChk.end(); ++it)
	{
		AddItem(it.key(), it.value());
	}
}

void XComboBox::AddItems(const QList<ItemInfo>& lstItemInfo)
{
	for (auto a : lstItemInfo)
	{
		AddItem(a.str, a.bChecked, a.userData);
	}
}

void XComboBox::AddItems(const QList<QString>& lstStr)
{
	for (auto a : lstStr)
	{ 
		AddItem(a, false);
	}
}
void XComboBox::AddItems(const QStringList& lstStr, QList<int> trueIndex)//by lxf
{
	for (int i=0; i<lstStr.size();i++)
	{
		QString a = lstStr.at(i);
		if (trueIndex.contains(i))	
			AddItem(a, true);		
		else
			AddItem(a, false);
	}
	
}
void XComboBox::AddItemContent(const QStringList& lstStr, QStringList currentStr)//by lxf
{
	for each (QString var in lstStr)
	{
		if (currentStr.contains(var) && var!=" ")
			AddItem(var, false);
		else
			AddItem(var, false);

	}
}
void XComboBox::RemoveItem(int idx)
{
	m_model.removeRow(idx);
	UpdateText();
}

void XComboBox::Clear()
{
	m_model.clear();
	UpdateText();
}

QStringList XComboBox::GetSelItemsText()
{
	QStringList lst;
	QString str = pLineEdit->text();
	if (str.isEmpty())
	{
		return lst;
	}
	else
	{
		/*return pLineEdit->text().split(",");*/
        return pLineEdit->text().split(QString::fromLocal8Bit("、"));
	}
}

QList<ItemInfo> XComboBox::GetSelItemsInfo()
{
	QList<ItemInfo> lstInfo;
	for (int i = 0; i < m_model.rowCount(); i++)
	{
		QStandardItem* item = m_model.item(i);
		if (item->checkState() == Qt::Unchecked) continue;

		ItemInfo info;
		info.idx = i;
		info.str = item->text();
		info.bChecked = true;
		info.userData = item->data(Qt::UserRole + 1);

		lstInfo << info;
	}

	return lstInfo;
}

QString XComboBox::GetItemText(int idx)
{
	if (idx < 0 || idx >= m_model.rowCount())
	{
		return QString::fromLocal8Bit("");
	}

	return m_model.item(idx)->text();
}

ItemInfo XComboBox::GetItemInfo(int idx)
{
	ItemInfo info;
	if (idx < 0 || idx >= m_model.rowCount())
	{
		return info;
	}

	QStandardItem* item = m_model.item(idx);
	info.idx = idx;
	info.str = item->text();
	info.bChecked = (item->checkState() == Qt::Checked);
	info.userData = item->data(Qt::UserRole + 1);

	return info;
}

void XComboBox::showPopup()
{
	emit showingPopup();
	QComboBox::showPopup();
}

void XComboBox::hidePopup()
{
	int width = this->view()->width();
	int height = this->view()->height();
	int x = QCursor::pos().x() - mapToGlobal(geometry().topLeft()).x() + geometry().x();
	int y = QCursor::pos().y() - mapToGlobal(geometry().topLeft()).y() + geometry().y();

	QRect rectView(0, this->height(), width, height);
	if (!rectView.contains(x, y))
	{
		emit hidingPopup();
		QComboBox::hidePopup();
	}
}

void XComboBox::mousePressEvent(QMouseEvent * event)
{
	QComboBox::mousePressEvent(event);
	event->accept();
}

void XComboBox::mouseReleaseEvent(QMouseEvent * event)
{
	QComboBox::mouseReleaseEvent(event);
	event->accept();
}

void XComboBox::mouseMoveEvent(QMouseEvent * event)
{
	QComboBox::mouseMoveEvent(event);
	event->accept();
}

void XComboBox::UpdateText()
{
	QStringList lstTxt;
	for (int i = 0; i < m_model.rowCount(); ++i)
	{
		QStandardItem* item = m_model.item(i);
		if (item->checkState() == Qt::Unchecked) continue;

		lstTxt << item->text();
	}

	//pLineEdit->setText(lstTxt.join(","));
    pLineEdit->setText(lstTxt.join(QString::fromLocal8Bit(",")));
	pLineEdit->setToolTip(lstTxt.join("\n"));
}

void XComboBox::sltActivated(int idx)
{
	QStandardItem* item = m_model.item(idx);
	if (nullptr == item) return;

	Qt::CheckState state = (item->checkState() == Qt::Checked) ? Qt::Unchecked : Qt::Checked;
	item->setCheckState(state);

	UpdateText();
}

使用:

void  tempTaskInformation::setXComboxWidget(QStringList& lstStr, QWidget &widget, QString lstStrCurrent)
{
	//QGridLayout* hLayout_00;
	//XComboBox * xcmb_00;
	xcmb_00 = new XComboBox();
	xcmb_00->setFixedHeight(34);
	QStringList currentList = lstStrCurrent.split(",");
	xcmb_00->AddItemContent(lstStr, currentList);
	xcmb_00->iniCompleter(lstStr);//模糊检索
	hLayout_00 = new QGridLayout();
	hLayout_00->addWidget(xcmb_00);
	hLayout_00->setMargin(0);
	widget.setLayout(hLayout_00);
	//widget.setFont(QFont(QString::fromLocal8Bit(" 微软雅黑 "), 12));
}
void  tempTaskInformation::changeXComboxWidget(QStringList& lstStr, QString lstStrCurrent)
{
	QStringList currentList = lstStrCurrent.split(",");
	xcmb_00->clear();
	xcmb_00->AddItemContent(lstStr, currentList);
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值