QListView自定义Item

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a844651990/article/details/84324560

前言

  要实现的效果类似网易云PC客户端本地音乐页面的效果:
在这里插入图片描述
  效果图:
效果图

实现

  QListWidget和QListView都能实现,先说一下两者的区别吧,QListWidget和QListView的主要区别在于QListView是基于Model,而QListWidget是基于Item,QListWidget继承于QListView。也就是说QListWidget插入数据的话我们只能通过 addItem 这个方法来实现,QListView插入数据的话我们是往model里面插入数据,而且我们还可以自定义自己的model,易于扩展,降低了数据冗余,提高了程序的效率。

实现方法大概有这么三种:

  1. 如果使用QListWidget的话,我们直接调用 setItemWidget 即可。
	void setItemWidget(QListWidgetItem *item, QWidget *widget)
  1. QListWidget和QListView都可以通过调用 setIndexWidget 实现。但是该方法只适合做静态数据的显示,不适合做一些插入、更新、删除操作的数据显示。
	void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget)
  1. 我们针对QListView实现自己的ItemDelegate。本文就是采用该种方法,重写ItemDelegate的paint函数。

首先实现自己要显示的数据结构体,需要用到Q_DECLARE_METATYPE宏

#include <QMetaType>

typedef struct {
    QString iconPath;
    QString singer;
    QString songsNb;
} MuItemData;

Q_DECLARE_METATYPE(MuItemData)

item的大小通过sizeHint函数设置:

QSize MuItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(index)
    return QSize(option.rect.width(), 50);
}

重写paint函数:

void MuItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if (index.isValid()) {
        painter->save();
        QVariant var = index.data(Qt::UserRole+1);
        MuItemData itemData = var.value<MuItemData>();

        // item 矩形区域
        QRectF rect;
        rect.setX(option.rect.x());
        rect.setY(option.rect.y());
        rect.setWidth(option.rect.width()-1);
        rect.setHeight(option.rect.height()-1);

        QPainterPath path;
        path.moveTo(rect.topRight());
        path.lineTo(rect.topLeft());
        path.quadTo(rect.topLeft(), rect.topLeft());
        path.lineTo(rect.bottomLeft());
        path.quadTo(rect.bottomLeft(), rect.bottomLeft());
        path.lineTo(rect.bottomRight());
        path.quadTo(rect.bottomRight(), rect.bottomRight());
        path.lineTo(rect.topRight());
        path.quadTo(rect.topRight(), rect.topRight());

        // 鼠标悬停或者选中时改变背景色
        if (option.state.testFlag(QStyle::State_MouseOver)) {
            painter->setPen(QPen(QColor("#ebeced")));
            painter->setBrush(QColor("#ebeced"));
            painter->drawPath(path);
        }
        if (option.state.testFlag(QStyle::State_Selected)) {
            painter->setPen(QPen(QColor("#e3e3e5")));
            painter->setBrush(QColor("#e3e3e5"));
            painter->drawPath(path);
        }

        // 绘制图片,歌手,数量位置区域
        QRectF iconRect = QRect(rect.left()+5, rect.top()+5, 40, 40);
        QRectF singerRect = QRect(iconRect.right()+5, iconRect.top(), rect.width()-10-iconRect.width(), 20);
        QRectF songNbRect = QRect(singerRect.left(), singerRect.bottom()+5, rect.width()-10-iconRect.width(), 20);

        painter->drawImage(iconRect, QImage(itemData.iconPath));
        painter->setPen(QPen(Qt::black));
        painter->setFont(QFont("Microsoft Yahei", 10));
        painter->drawText(singerRect, itemData.singer);

        painter->setPen(QPen(Qt::gray));
        painter->drawText(songNbRect, itemData.songsNb);

        painter->restore();
    }
}

插入数据:

#include <QStandardItemModel>
#include <QObject>
#include "Widget.h"
#include "ui_Widget.h"
#include "MuListItemData.h"
#include "MuItemDelegate.h"

const QStringList icons = {
    ":/images/HotDog.jpg", ":/images/li.jpg", ":/images/logo.jpg",
    ":/images/PACT.jpg", ":/images/yang.jpg", ":/images/zhang.jpg",
};
const QStringList singers = {
    "MC-Hotdog", "李荣浩", "Author",
    "PACT", "杨千嬅", "张震岳",
};

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    QStandardItemModel *pModel = new QStandardItemModel();
    for (int i=0; i<icons.size(); ++i) {
        QStandardItem *pItem = new QStandardItem;
        MuItemData itemData;
        itemData.singer = singers.at(i);
        itemData.songsNb = QString::number(i * i) + "首";
        itemData.iconPath = icons.at(i);
        pItem->setData(QVariant::fromValue(itemData), Qt::UserRole+1);
        pModel->appendRow(pItem);
    }

    MuItemDelegate *pItemDelegate = new MuItemDelegate(this);
    ui->listView->setItemDelegate(pItemDelegate);
    ui->listView->setModel(pModel);
}

Widget::~Widget()
{
    delete ui;
}

代码下载:

CSDN: https://download.csdn.net/download/a844651990/10798713
GitHub: https://github.com/FlyWM/MuListView

猜你喜欢

转载自blog.csdn.net/a844651990/article/details/84324560