QListView自定义Item

QListView自定义Item前言 要实现的效果类似网易云 PC 客户端本地音乐页面的效果 效果图 实现 QListWidget 和 QListView 都能实现 先说一下两者的区别吧 QListWidget 和 QListView 的主要区别在于 QListView 是基于 Model 而 QListWidget 是基于 Item QListWidget 继承于 QListView 也就是说 QListWidget 插入数据的话我们只能通过

前言

实现

  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  
     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  
     #include  
     #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; } 

代码下载:

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/204991.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午7:03
下一篇 2026年3月19日 下午7:04


相关推荐

  • Activiti初学者教程

    Activiti初学者教程http://wenku.baidu.com/view/bb7364ad4693daef5ff73d32.html1.初识Activiti1.1.工作流与工作流引擎工作流(workflow)

    2022年7月1日
    25
  • ISO27001标准

    ISO27001标准ISMSISMS 是组织开展并改进安全工作的系统的一套思路 方法 PDCA 项目准备项目范围确定组织部门无理地点 IT 资源初次做不建议做特别大 尽量周期比较快项目的组织高管重点参与部门协作部门项目沟通机制高层领导各个部门 ISMS 实施注意事项现状调研首先业务特征 组织结构及职责组织文化与管控模式其次 IT 规划 IT 制度文件 IT 基础设施资料 IT 应用系统资料 IT 运维程序等信息安全与相关的政策 策略 程序 记录及相关报告现状控制措施有没有是否充分是否有效期望调研方式文档审查问卷调查人员访谈覆盖面访谈提纲现场走查必

    2026年3月20日
    2
  • 感知机算法学习笔记(带例题及代码)

    感知机算法学习笔记(带例题及代码)感知机算法学习感知机感知机是二分类的线性分类模型 其输入为实例的特征向量 输出实例为类别 取 1 和 1 二值 属于判别模型 感知机学习旨在求出能够将训练数据集进行正确的分类的分离超平面的 为此 导入基于误分类的损失函数 利用梯度下降法对损失函数进行极小化 求得感知机模型 感知机具有简单易实现的优点 分为原始和对偶形式 感知机模型定义 称函数 y f x sign 全新的界面设计 将会带

    2026年3月26日
    2
  • 即梦Seedance2.0图片提示词生成技巧

    即梦Seedance2.0图片提示词生成技巧

    2026年3月12日
    2
  • java函数式编程实例(函数式编程实例)

    描述:一元运算,接受一个T类型参数,输出一个与入参类型一样的值源码:publicinterfaceUnaryOperatorextendsFunction{/***Returnsaunaryoperatorthatalwaysreturnsitsinputargument.**@paramth

    2022年4月12日
    67
  • 傅里叶、拉普拉斯、z变换常用公式合集「建议收藏」

    傅里叶、拉普拉斯、z变换常用公式合集「建议收藏」傅里叶变换常用信号的傅里叶变换傅里叶变换的性质傅里叶性质—典型变换对拉普拉斯常用信号的单边拉普拉斯变换拉普拉斯变换的性质z变换常用序列的z变换z变换的性质…

    2022年7月17日
    24

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号