目标:封装横向布局、自适应大小、支持缩放的QListWidget
1、QListWidget:列表控件 支持添加QListWidgetItem
2、QListWidget常用接口:
a)、 void setSelectionMode(QAbstractItemView::SelectionMode mode);---设置选中模式
QAbstractItemView::SingleSelection // 单选
QAbstractItemView::ContiguousSelection // 单选多选
QAbstractItemView::ExtendedSelection // 单选多选--支持鼠标框选
QAbstractItemView::MultiSelection // 多选
QAbstractItemView::NoSelection // 不能选中
b)、void setViewMode(ViewMode mode);----设置视图模式
QListView::ListMode // 从下至上
QListView::IconMode // 从左至右
c)、 void setFlow(Flow flow); ----此功能需要配合setViewMode 使用
QListView::LeftToRight
QListView::TopToBottom
d)、void setResizeMode(ResizeMode mode);---设置大小调整模式
QListView::Fixed // 固定
QListView::Adjust // 自适应
e)、void setMovement(Movement movement); ---设置移动方式
QListView::Static // 不能被用户移动
QListView::Free // 用户可以将项目拖放到视图中的任何位置
QListView::Snap // 移动时会对齐到指定的网格
f)、void setLayoutMode(LayoutMode mode);---项目的布局是应该立即生效还是延迟生效
QListView::SinglePass // 立即生效
QListView::Batched // 延迟生效
//头文件
#pragma once
#include <QListWidget>
#include <QListWidgetItem>
#include <QMouseEvent>
class HiBaseWidget;
class HiListWidget : public QListWidget
{
Q_OBJECT
public:
explicit HiListWidget(QWidget *parent = nullptr);
~HiListWidget();
public:
QListWidgetItem* GetItemByWidget(const QWidget *widget) const;
QListWidgetItem* GetItemByID(const QString &strID) const;
HiBaseWidget* GetBaseWidget(const QString &ID);
QList<QString> GetSelectedIDs() const;
public:
void SetSizeHint(const QSize &size);
void AddItem(HiBaseWidget* widget);
void RemoveItem(const QString &strID);
protected:
virtual void mousePressEvent(QMouseEvent *event) override;
protected slots:
void onItemSelectionChanged();
signals:
void sinalSeletedMode(bool bSingle);
private:
void updateSelected();
private:
QSize m_size;
QList<HiBaseWidget*> m_widgets;
bool m_bMultiSelection;
};
// Cpp
#include "HiListWidget.h"
#include "HiBaseWidget.h"
HiListWidget::HiListWidget(QWidget *parent)
: QListWidget(parent)
{
this->setSelectionMode(QAbstractItemView::SelectionMode::ExtendedSelection);
this->setViewMode(QListView::IconMode);
this->setFlow(QListWidget::LeftToRight);
this->setResizeMode(QListView::Adjust);
this->setMovement(QListView::Static);
this->setLayoutMode(QListView::SinglePass);
this->setWrapping(true);
this->setSpacing(5);
connect(this, &QListWidget::itemSelectionChanged, this, &HiListWidget::onItemSelectionChanged);
}
HiListWidget::~HiListWidget()
{
}
QListWidgetItem* HiListWidget::GetItemByWidget(const QWidget *widget) const
{
if (nullptr == widget)
{
return nullptr;
}
for (int var = 0; var < this->count(); ++var)
{
QListWidgetItem *pItem = item(var);
if (pItem)
{
if (widget == this->itemWidget(pItem))
{
return pItem;
}
}
}
return nullptr;
}
QListWidgetItem* HiListWidget::GetItemByID(const QString &strID) const
{
for (int var = 0; var < this->count(); ++var)
{
QListWidgetItem *pItem = item(var);
if (pItem)
{
HiBaseWidget *widget = dynamic_cast<HiBaseWidget*>(itemWidget(pItem));
if (widget && widget->getID() == strID)
{
return pItem;
}
}
}
return nullptr;
}
HiBaseWidget* HiListWidget::GetBaseWidget(const QString &ID)
{
for each (HiBaseWidget* var in m_widgets)
{
if (var->getID() == ID)
{
return var;
}
}
return nullptr;
}
QList<QString> HiListWidget::GetSelectedIDs() const
{
QList<QString> ids;
for each (HiBaseWidget* var in m_widgets)
{
if (var->isSelected())
{
ids.push_back(var->getID());
}
}
return ids;
}
void HiListWidget::SetSizeHint(const QSize &size)
{
if (size == m_size)
{
return;
}
m_size = size;
for (int var = 0; var < this->count(); ++var)
{
QListWidgetItem *pItem = item(var);
if (pItem)
{
pItem->setSizeHint(size);
HiBaseWidget *widget = dynamic_cast<HiBaseWidget*>(itemWidget(pItem));
if (widget)
{
widget->setFixedSize(size);
widget->update();
}
}
}
// 动态移动
this->doItemsLayout();
}
void HiListWidget::AddItem(HiBaseWidget* widget)
{
QListWidgetItem *item = new QListWidgetItem();
this->addItem(item);
item->setSizeHint(m_size);
this->setItemWidget(item, widget);
this->doItemsLayout();
m_widgets.append(widget);
}
void HiListWidget::RemoveItem(const QString &strID)
{
QListWidgetItem *pItem = GetItemByID(strID);
if (pItem)
{
HiBaseWidget *widget = dynamic_cast<HiBaseWidget*>(this->itemWidget(pItem));
if (widget)
{
m_widgets.removeAll(widget);
delete widget;
widget = nullptr;
}
this->removeItemWidget(pItem);
delete pItem;
pItem = nullptr;
}
}
void HiListWidget::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::RightButton)
{
QListWidgetItem *pItem = this->itemAt(event->pos());
if (pItem)
{
if (!pItem->isSelected())
{
this->clearSelection();
pItem->setSelected(true);
}
HiBaseWidget *widget = dynamic_cast<HiBaseWidget*>(itemWidget(pItem));
if (widget)
{
widget->doRightButtonClicked();
}
}
else
{
this->clearSelection();
}
}
QListWidget::mousePressEvent(event);
}
void HiListWidget::onItemSelectionChanged()
{
updateSelected();
}
void HiListWidget::updateSelected()
{
emit sinalSeletedMode(this->selectedItems().size() <= 1);
for (int var = 0; var < this->count(); ++var)
{
QListWidgetItem *pItem = item(var);
if (pItem)
{
HiBaseWidget *widget = dynamic_cast<HiBaseWidget*>(itemWidget(pItem));
if (widget)
{
widget->setSelected(pItem->isSelected());
}
}
}
}
//HiBaseWidget
#pragma once
#include <QFrame>
class HiBaseWidget : public QFrame
{
Q_OBJECT
public:
HiBaseWidget(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
virtual ~HiBaseWidget();
public:
// 重要ID、可以是节点ID、节目ID等
virtual QString getID() const = 0;
// 设置Widget选中
virtual void setSelected(const bool selected) = 0;
// 节点是否为选中状态
virtual bool isSelected() const = 0;
// 处理邮件弹框
virtual void doRightButtonClicked() = 0;
};