QListView

#ifndef MUITEMDELEGATE_H
#define MUITEMDELEGATE_H

#include <QStyledItemDelegate>

class MuItemDelegate : public QStyledItemDelegate
{
public:
    explicit MuItemDelegate(QObject *parent = nullptr);
    
    // painting
    void paint(QPainter *painter,
               const QStyleOptionViewItem &option, const QModelIndex &index) const override;

    QSize sizeHint(const QStyleOptionViewItem &option,
                   const QModelIndex &index) const override;
    
    bool editorEvent(QEvent *event, QAbstractItemModel *model,
                     const QStyleOptionViewItem &option, const QModelIndex &index) override;
};

#endif // MUITEMDELEGATE_H
#include <QPainter>
#include <QDebug>
#include "MuItemDelegate.h"
#include "MuListItemData.h"
#include "qcoreevent.h"
#include <QPainterPath>
#include <QCheckBox>

#include <QListView>
#include <QStandardItemModel>
#include <QStyledItemDelegate>
#include <QCheckBox>
#include <QLabel>
#include <QHBoxLayout>
#include <QSpacerItem>

MuItemDelegate::MuItemDelegate(QObject *parent)
    : QStyledItemDelegate{parent}
{
    lineHeight = 40;
}

void MuItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
    if (!index.isValid())
    {
        return;
    }
    
    auto getRectParam = [=](){
        double icoSize = 18;
        MuItemDelegate::MUITEM_PARAM_RECT muitemParamRect;
        muitemParamRect.leftRect = QRectF(0, 0, 10, lineHeight);
        muitemParamRect.checkBoxRect = QRectF(muitemParamRect.leftRect.topRight().x(), 0, icoSize, icoSize);
        muitemParamRect.iconRect = QRectF(muitemParamRect.checkBoxRect.topRight().x(), 0, icoSize, icoSize);
        muitemParamRect.titleRect = QRectF(muitemParamRect.iconRect.topRight().x(), 0, lineHeight, lineHeight);
        muitemParamRect.eyeIconRect = QRectF(muitemParamRect.titleRect.topRight().x(), 0, icoSize, icoSize);
        return muitemParamRect;
    };
    
    MuItemDelegate::MUITEM_PARAM_RECT muitemParamRect = getRectParam();
    
    // 创建父 QWidget 以容纳复选框和标签
    auto createWidget = [=](){    
        QHBoxLayout* layout = new QHBoxLayout();
        
        QSpacerItem *leftSpacerItem = new QSpacerItem(muitemParamRect.leftRect.width(), muitemParamRect.leftRect.height(), QSizePolicy::Fixed);
        layout->addItem(leftSpacerItem);
        
        // 创建复选框
        QCheckBox* checkBox = new QCheckBox();
        checkBox->setFixedSize(muitemParamRect.checkBoxRect.size().toSize());
        checkBox->setCheckable(true);
        checkBox->setChecked(index.data(Qt::CheckStateRole) == Qt::Checked);
        layout->addWidget(checkBox);
        
        // 创建第一个 QLabel 用于图标显示
        QLabel* iconLabel = new QLabel();
        QPixmap icon1 = index.data(Qt::DecorationRole).value<QPixmap>();
        iconLabel->setFixedSize(muitemParamRect.iconRect.size().toSize());
        iconLabel->setPixmap(icon1);
        layout->addWidget(iconLabel);
        
        // 创建第二个 QLabel 用于标题显示
        QLabel* titleLabel = new QLabel(index.data(Qt::DisplayRole).toString());
        layout->addWidget(titleLabel);
        
        // 创建第三个 QLabel 用于第二个图标显示
        QLabel* eyeIcoLabel = new QLabel();
        QPixmap icon2 = index.data(Qt::UserRole).value<QPixmap>();
        eyeIcoLabel->setPixmap(icon2);
        eyeIcoLabel->setFixedSize(muitemParamRect.eyeIconRect.size().toSize());
        layout->addWidget(eyeIcoLabel);
        
        // 设置布局属性
        layout->setContentsMargins(0 ,0, 0, 0);
        
        layout->setStretch(0, 1);
        layout->setStretch(1, 1);
        layout->setStretch(2, 1);
        layout->setStretch(3, 10);
        layout->setStretch(4, 1);
        
        return layout;
    };
    
    if(index.isValid())
    {
        QWidget* itemWidget = new QWidget();
        itemWidget->setGeometry(option.rect);
        QVBoxLayout* vlayout = new QVBoxLayout(itemWidget);
        vlayout->addLayout(createWidget());
        itemWidget->setGeometry(option.rect);
        painter->end();
        
        QPaintDevice* original_pdev_ptr = painter->device();
        painter->begin(original_pdev_ptr);
        if (option.state & QStyle::State_Selected) {
            painter->fillRect(option.rect, option.palette.highlight());
        } else {
            painter->fillRect(option.rect, option.palette.background());
        }
        itemWidget->render(original_pdev_ptr,
                           QPoint(option.rect.x(), option.rect.y()),
                           QRegion(0, 0, option.rect.width(), option.rect.height()),
                           QWidget::RenderFlag::DrawChildren);
        delete itemWidget;
    }
}

bool MuItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) 
{
    if (event->type() == QEvent::MouseButtonRelease)
    {
        if (index.data(Qt::CheckStateRole) == Qt::Checked)
        {
            model->setData(index, Qt::Unchecked, Qt::CheckStateRole);
        }
        else
        {
            model->setData(index, Qt::Checked, Qt::CheckStateRole);
        }
        return true;
    }
    return QStyledItemDelegate::editorEvent(event, model, option, index);
}

QSize MuItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(index)
    return QSize(0, lineHeight);
}
#ifndef LISTVIEW_H
#define LISTVIEW_H

#include <QWidget>
#include <QStandardItemModel>
#include "MuItemDelegate/muitemdelegate.h"

namespace Ui {
class ListView;
}

class ListView : public QWidget
{
    Q_OBJECT
    
public:
    explicit ListView(QWidget *parent = nullptr);
    ~ListView();
    
    QStandardItemModel *m_model;
    MuItemDelegate *customDelegate;
    
private:
    Ui::ListView *ui;
};

#endif // LISTVIEW_H
#include "listview.h"
#include "ui_listview.h"
#include "MuListItemData.h"
#include <QDebug>

ListView::ListView(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ListView)
{
    ui->setupUi(this);
    
    m_model = new QStandardItemModel();
    
    ui->listView->setModel(m_model);
    
    // 使用自定义委托
    customDelegate = new MuItemDelegate(this);
    ui->listView->setItemDelegate(customDelegate);
    
    // 添加一些项目到QListView
    QStringList stringList;
    stringList << "Item 1" << "Item 2" << "Item 3" << "Item 4" << "Item 5" 
               << "Item 6" << "Item 7" << "Item 8" << "Item 9" << "Item 10"
               << "Item 11" << "Item 12" << "Item 13" << "Item 14" << "Item 15"
               << "Item 16" << "Item 17" << "Item 18" << "Item 19" << "Item 20";
    for (const QString &text : qAsConst(stringList)) {
        QStandardItem *item = new QStandardItem(text);
        item->setCheckable(true);
        item->setCheckState(Qt::Unchecked);
        
        //设置图标和第二个图标(可以根据需要设置)
        item->setData(QPixmap(":/images/HotDog.jpg"), Qt::DecorationRole);
        item->setData(QPixmap(":/images/li.jpg"), Qt::UserRole);

        m_model->appendRow(item);
    }
}

ListView::~ListView()
{
    delete ui;
}
#include <QApplication>
#include "listview.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    ListView *listView = new ListView();
    listView->show();

    return a.exec();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nhfc99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值