实现通过带复选框的下拉框来为表格添加过滤条件
带复选框的下拉框
.h文件
cpp
#pragma once
#include <QCheckBox>
#include <QComboBox>
#include <QEvent>
#include <QLineEdit>
#include <QListWidget>
class TableComboBox : public QComboBox
{
Q_OBJECT
public:
TableComboBox(QWidget* parent = NULL);
~TableComboBox();
// 隐藏下拉框
virtual void hidePopup();
// 添加一条选项
void addItem(const QString& _text, const QVariant& _variant = QVariant());
// 添加多条选项
void addItems(const QStringList& _text_list);
// 返回当前选中选项
QStringList currentText();
// 返回当前选项条数
int count() const;
// 设置搜索框默认文字
void SetSearchBarPlaceHolderText(const QString _text);
// 设置文本框默认文字
void SetPlaceHolderText(const QString& _text);
// 下拉框状态恢复默认
void ResetSelection();
// 清空所有内容
void clear();
// 文本框内容清空
void TextClear();
// 设置选中文本--单
void setCurrentText(const QString& _text);
// 设置选中文本--多
void setCurrentText(const QStringList& _text_list);
// 设置搜索框是否禁用
void SetSearchBarHidden(bool _flag);
protected:
// 事件过滤器
virtual bool eventFilter(QObject* watched, QEvent* event);
// 滚轮事件
virtual void wheelEvent(QWheelEvent* event);
// 按键事件
virtual void keyPressEvent(QKeyEvent* event);
private slots:
// 文本框文本变化
void stateChange(int _row);
// 点击下拉框选项
void itemClicked(int _index);
signals:
// 发送当前选中选项
void selectionChange(const QString _data);
private:
// 下拉框
QListWidget* pListWidget;
// 文本框,搜索框
QLineEdit *pLineEdit, *pSearchBarEdit;
// 搜索框显示标志
bool isHidden;
// 下拉框显示标志
bool isShow;
};
.cpp文件
cpp
#include "PowerTableComboBox.h"
#include <QMessageBox>
#define FREEPTR(p) \
if (p != NULL) \
{ \
delete p; \
p = NULL; \
}
TableComboBox::TableComboBox(QWidget* parent)
: QComboBox(parent)
, isHidden(true)
, isShow(false)
{
pListWidget = new QListWidget();
pLineEdit = new QLineEdit();
pSearchBarEdit = new QLineEdit();
QListWidgetItem* currentItem = new QListWidgetItem(pListWidget);
pSearchBarEdit->setPlaceholderText("搜索...");
pSearchBarEdit->setClearButtonEnabled(true);
pListWidget->addItem(currentItem);
pListWidget->setItemWidget(currentItem, pSearchBarEdit);
pLineEdit->setReadOnly(true);
pLineEdit->installEventFilter(this);
pLineEdit->setStyleSheet("QLineEdit:disabled{background:rgb(233,233,233);}");
this->setModel(pListWidget->model());
this->setView(pListWidget);
this->setLineEdit(pLineEdit);
connect(this, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, &TableComboBox::itemClicked);
}
TableComboBox::~TableComboBox()
{
FREEPTR(pLineEdit);
FREEPTR(pSearchBarEdit);
}
void TableComboBox::hidePopup()
{
isShow = false;
int width = this->width();
int height = this->height();
int x = QCursor::pos().x() - mapToGlobal(geometry().topLeft()).x() + geometry().x();
int y = QCursor::pos().y() - mapToGlobal(geometry().topLeft()).y() + geometry().y();
if (x >= 0 && x <= width && y >= this->height() && y <= height + this->height())
{
}
else
{
QComboBox::hidePopup();
}
}
void TableComboBox::addItem(const QString& _text, const QVariant& _variant)
{
Q_UNUSED(_variant);
QListWidgetItem* item = new QListWidgetItem(pListWidget);
QCheckBox* checkbox = new QCheckBox(this);
checkbox->setText(_text);
pListWidget->setItemWidget(item, checkbox);
pListWidget->addItem(item);
connect(checkbox, &QCheckBox::stateChanged, this, &TableComboBox::stateChange);
checkbox->setChecked(true);
}
void TableComboBox::addItems(const QStringList& _text_list)
{
for (const auto& text_one : _text_list)
{
addItem(text_one);
}
}
QStringList TableComboBox::currentText()
{
QStringList text_list;
if (!pLineEdit->text().isEmpty())
{
// 以空格为分隔符分割字符串
text_list = pLineEdit->text().split(' ');
}
return text_list;
}
int TableComboBox::count() const
{
int count = pListWidget->count() - 1;
if (count < 0)
{
count = 0;
}
return count;
}
void TableComboBox::SetSearchBarPlaceHolderText(const QString _text)
{
pSearchBarEdit->setPlaceholderText(_text);
}
void TableComboBox::SetPlaceHolderText(const QString& _text)
{
pLineEdit->setPlaceholderText(_text);
}
void TableComboBox::ResetSelection()
{
int count = pListWidget->count();
for (int i = 1; i < count; i++)
{
QWidget* widget = pListWidget->itemWidget(pListWidget->item(i));
QCheckBox* check_box = static_cast<QCheckBox*>(widget);
check_box->setChecked(false);
}
}
void TableComboBox::clear()
{
pLineEdit->clear();
pListWidget->clear();
QListWidgetItem* currentItem = new QListWidgetItem(pListWidget);
pSearchBarEdit->setPlaceholderText("搜索...");
pSearchBarEdit->setClearButtonEnabled(true);
pListWidget->addItem(currentItem);
pListWidget->setItemWidget(currentItem, pSearchBarEdit);
SetSearchBarHidden(isHidden);
}
void TableComboBox::TextClear()
{
pLineEdit->clear();
ResetSelection();
}
void TableComboBox::setCurrentText(const QString& _text)
{
int count = pListWidget->count();
for (int i = 1; i < count; i++)
{
QWidget* widget = pListWidget->itemWidget(pListWidget->item(i));
QCheckBox* check_box = static_cast<QCheckBox*>(widget);
if (_text.compare(check_box->text()))
check_box->setChecked(true);
}
}
void TableComboBox::setCurrentText(const QStringList& _text_list)
{
int count = pListWidget->count();
for (int i = 1; i < count; i++)
{
QWidget* widget = pListWidget->itemWidget(pListWidget->item(i));
QCheckBox* check_box = static_cast<QCheckBox*>(widget);
if (_text_list.contains(check_box->text()))
check_box->setChecked(true);
}
}
void TableComboBox::SetSearchBarHidden(bool _flag)
{
isHidden = _flag;
pListWidget->item(0)->setHidden(isHidden);
}
bool TableComboBox::eventFilter(QObject* watched, QEvent* event)
{
if (watched == pLineEdit && event->type() == QEvent::MouseButtonRelease && this->isEnabled())
{
showPopup();
return true;
}
return false;
}
void TableComboBox::wheelEvent(QWheelEvent* event)
{
Q_UNUSED(event);
}
void TableComboBox::keyPressEvent(QKeyEvent* event)
{
QComboBox::keyPressEvent(event);
}
void TableComboBox::stateChange(int _row)
{
Q_UNUSED(_row);
QString selected_data("");
int count = pListWidget->count();
for (int i = 1; i < count; i++)
{
QWidget* widget = pListWidget->itemWidget(pListWidget->item(i));
QCheckBox* check_box = static_cast<QCheckBox*>(widget);
if (check_box->isChecked())
{
// 添加空格做为分割符
selected_data.append(check_box->text()).append(" ");
}
}
selected_data.chop(1);
if (!selected_data.isEmpty())
{
pLineEdit->setText(selected_data);
}
else
{
pLineEdit->clear();
}
// 文字从最左边开始显示
pLineEdit->setToolTip(selected_data);
pLineEdit->setSelection(0, 0);
pLineEdit->setCursorPosition(0);
emit selectionChange(selected_data);
}
void TableComboBox::itemClicked(int _index)
{
if (_index != 0)
{
QCheckBox* check_box = static_cast<QCheckBox*>(pListWidget->itemWidget(pListWidget->item(_index)));
check_box->setChecked(!check_box->isChecked());
}
}
表格过滤器代理类
cpp
class TableProxyModel : public QSortFilterProxyModel
{
public:
TableProxyModel (QObject* parent = nullptr)
: QSortFilterProxyModel(parent)
{}
protected:
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override
{
QModelIndex targetTypeIndex = sourceModel()->index(source_row, 0, source_parent);
QModelIndex boomNameIndex = sourceModel()->index(source_row, 1, source_parent);
QModelIndex destructionDegreeIndex = sourceModel()->index(source_row, 2, source_parent);
QString typeText = sourceModel()->data(targetTypeIndex).toString();
QString nameText = sourceModel()->data(boomNameIndex).toString();
int levelText = sourceModel()->data(destructionDegreeIndex).toInt();
if (!isFilter)
{
return true;
}
bool matchType = false;
bool matchName = false;
bool levelText = false;
for (QString type : sType)
{
if (typeText == type)
{
matchType = true;
break;
}
}
for (QString name : sName)
{
if (nameText == name)
{
matchName = true;
break;
}
}
for (int level: nLevelVec)
{
if (levelText == level)
{
matchLevel = true;
break;
}
}
if (matchLevel && matchName && matchType)
{
return true;
}
return false;
}
public:
QStringList sType;
QStringList sName;
QVector<int> nLevelVec;
bool isFilter = false;
};
表格设置代理关联下拉框内容变更
添加代理
cpp
tableView = new QTableView;
proxyModel = new TableProxyModel;
// 设置过滤规则来执行过滤
proxyModel->setFilterRole(Qt::DisplayRole);
proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
proxyModel->setSourceModel(model);
tableView->setModel(proxyModel);
下拉框关联表格代理
- 通过信号与槽关联
cpp
connect(typeBox, &TableComboBox::selectionChange, this, &ShowTableView::filterBtnClick);
- 获取下拉框内容传到代理类做过滤
cpp
void ShowTableView::filterBtnClick(QString)
{
// 复位
proxyModel->isFilter = true;
proxyModel->sType.clear();
proxyModel->sName.clear();
proxyModel->nLevelVec.clear();
// 获取筛选条件
proxyModel->sType = typeBox->currentText();
proxyModel->sName= boomNameBox->currentText();
for (QString level: levelBox->currentText())
{
proxyModel->nLevelVec.push_back(level.toInt());
}
proxyModel->setFilterFixedString("");
}
- 取消过滤,复位
cpp
void ShowTableView::noFilterBtnClick()
{
proxyModel->isFilter = false;
proxyModel->setFilterFixedString("");
}
截图
- 过滤前
- 过滤后