小鱼人

黄沙百战穿金甲,不破楼兰终不还。

  • 主页
  • 生活
  • 归档
所有文章 友链 关于我
收藏夹

小鱼人

黄沙百战穿金甲,不破楼兰终不还。

  • 主页
  • 生活
  • 归档

QListView Item 代理

2020-01-01

2020年新的一天,祝大家元旦快!路漫漫其修远兮,吾将上下而求索。

去年的效果跟目前的效果对比

  这个是去年做的效果,当时得到了脏脏鱼大佬跟TM大佬的帮助,说实话当时能做到这样的效果已经不错了,但是还是留下些遗憾。
没有达到最理想的效果,当时受制于QStandarItem只能设置一个QIcon跟一个Text,最终只能做出这样的效果。

这个是前段时间实现的效果,得到了输入大佬跟猫咪大佬的帮助,用代理实现了我最终想要的效果,可以看到增加了阴影范围绘制跟曲
线绘制,我认为这东西是我今年做的算不错的东西啦。

再来一个Gif图看看效果

实现

  代理本质上利用了Qt的绘制功能,也就是说你想绘制啥都行,绘制图片,绘制曲线,绘制text。因为我的QListView的item,不同的
Item可能会需要用到不同的曲线、不同的阴影范围、不同的图片(当然我这里暂时用的同一张图片)和不同的text。基本上不同的东西就这些了,
当然可能还有数量的不同。所以应该为代理的item创建一个专属的存放数据的结构体。

mulistitemdata.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef MULISTITEMDATA_H
#define MULISTITEMDATA_H

#include <QPointF>
#include <QMetaType>

typedef struct
{
QVector<QPointF>shadow; //阴影范围数据
QString iconPath; //icon路径
QString text; //item名称
bool able; //禁用或者开启绘制状态图标 详细请查看muitemdelegate paint函数
bool select; //选择图标或者禁用图标状态
} MuItemData;

Q_DECLARE_METATYPE(MuItemData)

#endif // MULISTITEMDATA_H

muitemdelegate.h

这里就是我们的代理相关的头文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifndef MUITEMDELEGATE_H
#define MUITEMDELEGATE_H

#include <QVector>
#include <QPointF>
#include <QStyledItemDelegate>

class MuItemDelegate : public QStyledItemDelegate
{
public:
MuItemDelegate(QObject *parent = nullptr);
~MuItemDelegate();
void Init();

/********************************************
* @return 返回x的坐标长度
* @grid 单个格子的x大小
* @double 频率大小
********************************************/
double GetX(double freq, double grid = 10.0);

void SetAudioGram(const QVector<double>&left, const QVector<double>&right);

// painting
void paint(QPainter *painter,
const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;

QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const Q_DECL_OVERRIDE;
static QVector<QPointF>left; //左耳曲线图
static QVector<QPointF>right; //右耳曲线
};

#endif // MUITEMDELEGATE_H

muitemdelegate.cpp

  绘制相关过程都在paint函数里面这里绘制你需要得到的效果。
sizeHint函数这里180是你item的高度,这个你一定要设置下,它会影响你item画布的高度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include "MuItemDelegate.h"
#include "MuListItemData.h"
#include <qmath.h>
#include <QPainter>
#include <QDebug>

//静态数据成员定义
QVector<QPointF>MuItemDelegate::left; //左耳曲线图
QVector<QPointF>MuItemDelegate::right; //右耳曲线

MuItemDelegate::MuItemDelegate(QObject *parent) :
QStyledItemDelegate(parent)
{
Init();
}
MuItemDelegate::~MuItemDelegate()
{
left.clear();
right.clear();
}
void MuItemDelegate::Init()
{
left.resize(11);
right.resize(11);
for (int i = 0; i < left.size(); i++)
{
left[i].setY(-1);
}
for (int i = 0; i < right.size(); i++)
{
right[i].setY(-1);
}
/****数据初始化过程省略......****/

}
double MuItemDelegate::GetX(double freq, double gridx)
{
/***********数据转换代码省略...*******/
return a;
}
void MuItemDelegate::SetAudioGram(const QVector<double> &mleft, const QVector<double> &mright)
{
/****数据初始化过程省略......****/

}
void MuItemDelegate::paint(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const
{

if (index.isValid())
{
p->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)) {
//QStyledItemDelegate::paint(painter, option, index);
}
if (option.state.testFlag(QStyle::State_Selected)) {
QStyledItemDelegate::paint(p, option, index);
}

// 绘制图片,歌手,数量位置区域
QRectF iconRect = QRect(rect.left() + (rect.right() - rect.left()) / 2 - 25, rect.top() + 12, 50, 50);
QRectF singerRect = QRect(rect.left(), rect.top() + 70, 110, 40);
p->setRenderHint(QPainter::Antialiasing, true);//设置反锯齿渲染模式
p->drawImage(iconRect, QImage(itemData.iconPath));
p->setPen(QPen(QColor(45, 62, 75), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
p->setFont(QFont("Microsoft YaHei", 9, QFont::Medium, false));
p->drawText(singerRect, Qt::AlignCenter, itemData.text);


if (itemData.able)
{
if (itemData.select)
{
p->drawImage(QRect(rect.left() + 4, rect.top() + 50, 24, 24),
QImage(":/MainWindow/Resources/icon/ok24.png"));
}
else
{
//警告不匹配图片
p->drawImage(QRect(rect.left() + 4, rect.top() + 50, 24, 24),
QImage(":/MainWindow/Resources/icon/cancel24.png"));
}
}

/*p->drawImage(QRect(rect.left() + 77, rect.top() + 50, 32, 32),
QImage(":/MainWindow/Resources/icon/forbidden.png"));*/

//绘制光亮曲线点
p->setBrush(QBrush(QColor(250, 250, 250)));
p->setPen(QPen(QColor(131, 134, 145), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
p->setRenderHint(QPainter::Antialiasing, false);//设置反锯齿渲染模式
p->drawRoundedRect(QRect(rect.left() + 25, rect.top() + 110, 60, 60), 2, 2);
p->translate(rect.left() + 25, rect.top() + 110);

//阴影范围曲线图
const double Y = 60.0 / 7.0;
QPainterPath pathShadow;
if (0 != itemData.shadow.size())
{
itemData.shadow[0].setY((itemData.shadow[0].y() / 20.0) * Y);
pathShadow.moveTo(itemData.shadow[0]);
for (int i = 1; i < itemData.shadow.size(); i++)
{
itemData.shadow[i].setY((itemData.shadow[i].y() / 20.0) * Y);
pathShadow.lineTo(itemData.shadow[i]);
}
}
QBrush brush{ QColor(50,50,50,50),Qt::SolidPattern }; //阴影画刷颜色
p->setBrush(brush);
p->setPen(Qt::NoPen);
p->setRenderHint(QPainter::Antialiasing, true);//设置反锯齿渲染模式
p->drawPath(pathShadow);

//右耳曲线
p->setRenderHint(QPainter::Antialiasing, true);//设置反锯齿渲染模式
p->setPen(QPen(QColor(196, 42, 31, 255), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
QPainterPath pathright;
/*********曲线数据装过程载省略***********/
p->setBrush(Qt::NoBrush);
p->drawPath(pathright);


//左耳曲线
p->setPen(QPen(QColor(0, 117, 180, 255), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
QPainterPath pathleft;
/*********曲线数据装过程载省略***********/
p->drawPath(pathleft);

p->restore();
//QStyledItemDelegate::paint(painter, option, index);
}
}
QSize MuItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(index)
return QSize(option.rect.width(), 180);
}

最后当然是要知道怎么使用这玩意了

万事俱备,只欠东风!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
QStandardItemModel *model = new QStandardItemModel();//获取项目的根节点

const int SIZE = 16; //这里我创建了16个项
for (int i = 0; i < SIZE; i++)
{
auto pitem = new QStandardItem;//这个地方就用到了item数据结构,在paint会用到它
MuItemData itemData;
itemData.shadow = ReturnItemShadow(i);
itemData.iconPath = ReturnItemIconPath(i);
itemData.text = ReturnItemText(i);
itemData.able = false;
itemData.select = true;
//pitem->setFont(QFont("Microsoft YaHei", 9, QFont::Normal, false));
pitem->setData(QVariant::fromValue(itemData), Qt::UserRole + 1);
model->appendRow(pitem);
}
MuItemDelegate *pItemDelegate = new MuItemDelegate(this); //创建代理
ui->listView->setItemDelegate(pItemDelegate);//设置代理
ui->listView->setModel(model);//为QListView设置model

补充

  你的item数量或者需要绘制的东西可能是需要改变的,如果需要改变item数量,重新new再设置model,它自己会将之前的item delete掉
另外要取得不同的绘制就需要像我这里设置不同的状态开关,itemData.able/itemData.select之类的。好了再次祝大家工作顺利!

赏

谢谢你请我吃糖果

支付宝
微信
  • Qt
  • Qt

扫一扫,分享到微信

微信分享二维码
Git 小技巧
那些美好的过往——致2019年
  1. 1. 去年的效果跟目前的效果对比
  2. 2. 实现
  3. 3. mulistitemdata.h
  4. 4. muitemdelegate.h
  5. 5. muitemdelegate.cpp
  6. 6. 最后当然是要知道怎么使用这玩意了
  7. 7. 补充
© 2025 小鱼人
浙ICP备2021012892号
        Hexo
Theme Yilia by Litten
本站总访问量46169次
  • 所有文章
  • 友链
  • 关于我

tag:

  • algorithms
  • git
  • blender
  • bat
  • cmake
  • C++
  • SQLite
  • Landscape
  • LeetCode
  • life
  • markdown
  • system
  • Qt
  • qt-opengl
  • qss
  • UE
  • QML
  • UE5
  • VS
  • Windows

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 老服务器博客迁移到新服务器

    2024-04-08

  • cmake-tutorial-5

    2024-03-24

    #cmake

  • cmake-tutorial-4 5

    2024-03-23

    #cmake

  • cmake-tutorial-3

    2024-03-19

    #cmake

  • cmake-cookbook 第二章简要内容

    2024-03-18

    #cmake

  • 修复win10 系统(photo viewer)隐藏看不了 PNG JPG 图像的问题

    2024-03-16

    #Windows

  • cmake system-information

    2024-03-15

    #cmake

  • cmake-cookbook 第一章简要内容

    2024-03-15

    #cmake

  • cmake 构建指令

    2024-03-15

    #cmake

  • Git 常用的一些指令

    2023-09-17

    #git

  • 面试经验分享

    2023-06-18

  • C++数据模型 (LP32 ILP32 LP64 ILP64 LLP64)

    2023-03-06

    #C++

  • Begin Play | Niagara

    2022-12-23

    #UE

  • BeginPlay | Audio

    2022-12-23

    #UE

  • Begin Play | Gameplay

    2022-12-23

    #UE

  • Begin Play | Rendering

    2022-12-23

    #UE

  • Begin Play | World Building

    2022-12-23

    #UE

  • Begin Play | Blueprints

    2022-12-23

    #UE

  • Begin Play | Programming

    2022-12-23

    #UE

  • Begin Play | Engine Structure

    2022-12-23

    #UE

  • UE 学习 BeginPlay

    2022-12-23

    #UE

  • EPIC 代码规范

    2022-12-14

    #UE

  • 用Navicat工具执行vacuum指令给数据库瘦身

    2022-12-06

    #SQLite

  • Landscape 地形制作工具

    2022-11-13

    #Landscape

  • Blender 启用(Alt+LMB)旋转3D坐标系统

    2022-11-02

    #blender

  • LeetCode 3(无重复字符的最长子串)

    2022-08-02

    #LeetCode

  • LeetCode 739(每日温度)

    2022-08-01

    #LeetCode

  • LeetCose 781(森林中的兔子)

    2022-07-30

    #LeetCode

  • LeetCode 1190(反转每对括号间的子串)

    2022-07-29

    #LeetCode

  • LeetCode 45(跳跃游戏 II)

    2022-07-28

    #LeetCode

  • UE学习【从入坑到入坟】

    2022-06-17

    #UE

  • UE5 基于Niagara系统的模拟鸟群飞行 (初步效果)

    2022-06-02

    #UE5

  • 搭建个人博客环境的简要步骤Git+Nodejs+Hexo (Windows下)

    2022-05-25

    #git

  • C++ 转载汇总

    2021-12-28

    #C++

  • UnrealEngine Niagara模块创建条带效果

    2021-05-25

    #UE

  • UnrealEngine Niagara模块创建粒子光源

    2021-05-25

    #UE

  • UnrealEngine Niagara模块中的Sprite粒子效果 (网格体-气球)

    2021-05-21

    #UE

  • UnrealEngine Niagara模块中的Sprite粒子效果(GPU上跑)

    2021-05-21

    #UE

  • UnrealEngine Niagara模块中的Sprite粒子效果 (CPU上跑)

    2021-05-21

    #UE

  • 解决UnrealEngine项目编译后每次都需要重新编译的坑

    2021-04-17

    #UE

  • Visual Studio + Qt 解决项目类名无法高亮问题(关键字会高亮,类名函数名无法高亮,没有智能提示)

    2020-11-14

    #VS

  • Qt 下生成Json文件

    2020-09-19

    #Qt

  • Qt 利用xPath快速查询.xml里面的资源

    2020-08-07

    #Qt

  • Qt 翻译文件整体输出到一个.ts文件

    2020-07-27

    #Qt

  • Qt Visual Studio Tools 工具使用文档

    2020-07-25

    #VS

  • Visual Studio 项目属性含义

    2020-07-25

    #VS

  • Visual Studio 编译错误与警告含义

    2020-07-25

    #VS

  • Visual Studio 下创建 Qt 类库

    2020-07-25

    #Qt

  • Visual Studio 解决方案 .sln文件的项目类型 GUID

    2020-07-05

    #VS

  • Visual Studio 解决方案 .sln文件 解读

    2020-07-05

    #VS

  • Qt 信号默认支持的类型

    2020-06-16

    #Qt

  • SQLite 数据类型

    2020-06-06

    #SQLite

  • UE 用vs2019打开UnrealEngine项目

    2020-05-29

    #UE

  • UE 注册虚幻账号并访问UnrealEngine开源项目

    2020-05-29

    #UE

  • Qt 弹出界面

    2020-05-05

    #Qt

  • Qt 利用QAxObject解析excel文件

    2020-05-05

    #Qt

  • Qt 使提升控件类仍然支持QSS

    2020-05-05

    #qss

  • Windows10 操作系统设置默认语言为英文

    2020-03-14

    #Windows

  • Visual Studio 2019设置默认语言为英文

    2020-03-14

    #VS

  • 记录此刻

    2020-03-03

    #life

  • Centos7 + Gitlab源代码管理

    2020-01-16

    #git

  • Git 小技巧

    2020-01-11

    #git

  • QListView Item 代理

    2020-01-01

    #Qt

  • 那些美好的过往——致2019年

    2019-12-31

    #life

  • Batch 命令

    2019-12-26

    #bat

  • Batch 脚本简介

    2019-12-26

    #bat

  • Qt Qt实现圆角界面

    2019-12-13

    #Qt

  • Qt 消除 "libpng warning iCCP known incorrect sRGB profile" 警告

    2019-12-04

    #Qt

  • Git 删除文件或目录操作

    2019-11-29

    #git

  • Git 移动文件或目录操作

    2019-11-29

    #git

  • Visual Studio 2019 + Qt 工程目录重组织

    2019-11-28

    #VS

  • Windows 下注册dll

    2019-11-25

    #Windows

  • Qt 利用QHash存储曲线点

    2019-11-23

    #Qt

  • Git 基础(一)

    2019-11-06

    #git

  • Git 入门

    2019-11-05

    #git

  • Qt 利用QPainter绘制热力图

    2019-09-25

    #Qt

  • 异常控制流 (一)

    2019-09-20

    #system

  • C++ 内存错误信息

    2019-09-04

    #C++

  • Qt 遍历ui对象

    2019-08-19

    #Qt

  • Qt Quick 第一个quick程序

    2019-08-07

    #QML

  • Qt 利用QSS在button里面显示多张图

    2019-08-05

    #qss

  • Qt QSettings的在Win7下操作注册表信息

    2019-07-30

    #Qt

  • Qt 利用QToolButton实现菜单按钮的效果

    2019-07-29

    #Qt

  • 算法 (二) 堆排序

    2019-07-17

    #algorithms

  • 算法 (一) 选择排序

    2019-07-16

    #algorithms

  • qt-opengl(五)基于assimp库加载模型

    2019-07-16

    #qt-opengl

  • qt-opengl(四)纹理贴图

    2019-07-15

    #qt-opengl

  • qt-opengl(三)着色器

    2019-07-13

    #qt-opengl

  • qt-opengl(二) 你好三角形!

    2019-07-07

    #qt-opengl

  • qt-opengl(一) OpenGL简介

    2019-07-04

    #qt-opengl

  • qt-opengl-coordinate-system

    2019-07-04

  • Qt 打包发布

    2019-06-25

    #Qt

  • Qt 绘图裁剪

    2019-05-31

    #Qt

  • C++ 声明

    2019-05-18

    #C++

  • C++ 类

    2019-05-18

    #C++

  • 修改svg图片的颜色

    2019-05-15

  • C++ final关键字

    2019-05-05

    #C++

  • C++ 函数指针

    2019-04-27

    #C++

  • C++ 静态成员

    2019-04-14

    #C++

  • MarkDown 代码块高亮支持的语言

    2019-04-13

    #markdown

  • Git 忽略文件

    2019-04-12

    #git

  • C++ 友元

    2019-04-09

    #C++

  • 来自远方的你

    2019-04-01

    #life

  • QTableView获取当前选中行的字段内容

    2019-03-20

    #Qt

  • 代码被其它程序翻译成不同的格式

    2019-03-13

    #system

  • Win10系统下基于gitblit搭建git服务器

    2019-03-10

    #git

  • 各位大佬!小鱼人的博客终于上线啦!

    2019-03-09

    #life

  • 众里寻他千百度

    2019-03-07

    #life

  • 公孙二狗
  • 夜叉大佬
  • TM大佬(社会我TM,人猛话不多)
  • 千古大佬
  • 涛哥知乎专栏
  • 建波
  • 泡沫o0(写的很有深度,配图经典)
小鱼人,
毕业于南昌大学,在杭州工作

热爱编程工作
目前是做C++/Qt界面开发一枚
黄沙百战穿金甲,不破楼兰终不还。

希望学习更多的IT知识。