前言:

今天看到一个好玩的 qt 官方的 demo

可以把图片 变为 一个个灰度的像素点

先来看一下

这个是 qt 的图片

这个是我加载的 我的头像

不过 看 这个 demo
需要了解 Qt 的 MVD 模式

model view delegate

如果你没有听说过 mvd mvc 应该听说过吧 model view control

qt 这里把control 换成了 delegate 委托 其实差不多

我这里做个简单的介绍 大体了解熟悉 m v d

mvd(model - view - delegate)

很早之前 list 或者 view 在加载数据 进行显示时 如果数据量比较大 就会比较卡
比如 5w 条数据,他的内部的实现逻辑是 把这些数据全部加载到内存
但是他一页就显示 100行数据
后面为了解决这个问题 就改为 既用既加载 用100行数据 那么我就只加载100行
翻页或者下拉滑动条 我在加载 下面的数据到内存
又引来了个新问题 如果我快速的翻页 或者 拖拉滑动条 那么也会出现 卡顿 白屏等
数据加载跟不上的现象

让一个类 来处理数据的加载和显示 交互 难免太庞大

这个 MVD 就出来了

下面挂几个结构图 说一下 MVD


Data 就是 数据 比如 从 文件中加载,数据库中加载 ,网口 ,串口数据 等

Model 类 负责加载数据

View类 负责显示数据,具体显示什么样的数据,全都有 delegate 来决定

Delegate 负责 把 model 的数据 做一些处理 给 view 显示
比如 model 的数据是 用户消费信心
delegate 可以 根据不同的形式 paint 成 柱状图 饼图 条形图 给到 view 显示
view 用户操作界面 修改了一些 信息 还是通过 delegate 去修改 model

这里就做一些简单的 介绍
具体的 MVD 还是要去看 MVD 的文章

系统提供模式 这个模式 只能完成一些基本的简单的功能
如果想完成一些其他的 我们要重写 model 和 delegate

这个 demo 也就是这样的 操作 咱们来看一下

Pixelator Example

介绍:
默认情况下,QTreeView、QTableView和QListView使用一个标准的项目委托来显示和编辑一组公共数据类型,这对于许多应用程序来说已经足够了。但是,应用程序可能需要以特定的方式表示数据项,或者为呈现更专门的数据类型提供支持,这通常需要使用自定义委托

在本例中,我们将展示如何使用自定义委托来修改标准视图的外观。为此,我们实现了以下组件:
一种模型,它将图像中的每个像素表示为一个数据项,其中每个数据项包含对应像素的亮度值。
自定义委托,它使用模型提供的信息将每个像素表示为白色背景上的黑色圆圈,圆圈的半径对应于像素的黑暗。

此示例对于希望实现自己的表模型或自定义委托的开发人员可能很有用.

还是先看一下 类的结构

一个 自定义的 model imagemodel
一个 自定义的 delegate pixeldelegate
一个 mainwindow 主界面
一个 main 函数

还有 一个资源文件 qt.png 64* 64 像素的

ok 咱们来看 main 函数

main

初始化 资源

实例化 mainwindow

打开了一个图片

MainWindow

这个 Example 有个 打印图片的 功能 咱们这里就不看了 只看 MVD 的模式 把灰度图显示出来

类结构也很简单

ImageModel 等会看

看下 openImage

这个函数也没啥 就是加载一个 本地的图片
然后 更新一下 view

mainwindow 我们只需要看这一点就够了

一个 tableView

setShowGrid 显示不显示网格 效果如下

这是 不显示 网格

这是显示网格

可以查一下 就是 64x64 行列 因为这个图片 就是 64*64像素的 每个格子 一个像素点

view->setModel(model);
PixelDelegate *delegate = new PixelDelegate(this);
view->setItemDelegate(delegate);

给 view 设置了 model 是我们的 ImageModel
给 view 设置了委托delegate 是 我们的PiexlDelegate

所以我们主要看 这两个类就行了

ImageModel


由于我们只需要一个简单的只读表模型,所以我们只需要实现一些函数来指示图像的维数并向其他组件提供数据。

这个函数 在上面说的 加载 image 有调用这个接口


这个函数返回就是 行和列 就是返回的 64*64

由于图像是一个简单的二维结构,所以这些函数的父参数是未使用的。它们都简单地从底层图像对象返回相关大小。
data()函数返回与给定模型索引对应的项的数据,其格式适合于特定的角色

:这个函数 就是数据函数了 把 图片转为灰度显示的函数了

在这个实现中,我们只检查模型索引是否有效,并且请求的角色是DisplayRole。如果是,则返回图像中相关像素的灰度值;否则,将返回空模型索引。
这个模型可以和QTableView一起显示图像中像素的整数值。但是,我们将实现一个自定义委托来以更艺术的方式显示此信息

拆开来看
modelImage.pixle(index.column(),indelx.row())

返回给定像素的颜色 (传入的是像素点位置)

这个就是 返回的灰度值 传入 rgb

我们返回(1,1)作为标题项的大小提示。如果我们不这样做,标题将默认为更大的尺寸,从而阻止我们显示非常小的项目(可以使用像素大小组合框来指定)。

ok 到这这里类就结束了

这个类的作用就是数据 数据就是 一张图片每个像素点的 灰度值
一共 64*64个像素点

那么 data 函数就执行 64*64次

那么灰度值只是一个int 数字啊
具体怎么显示出来的 要看 delegate 是怎么实现的了

PixelDelegate

这个类只提供了委托的基本特性,我们子类化QAbstractItemDelegate而不是QItemDelegate。
我们只需要在这个类中重新实现paint()和sizeHint()。
但是,我们还提供了一个特定于委托的setPixelSize()函数,这样我们就可以通过信号和插槽机制来更改委托的行为。

这个 setPixelSize()函数 就是

修改这个通过信号槽 改变 私有变量 pixelSize

默认是 12px


这里说一下 参数 QmodelIndex &indelx
view和delegate都可以使用QModelIndex,但是view只能使用QModelIndex进行读取,delegate只能修改。 所以 要获取 model 的数据 都是 通过 这个接口 modelIndex .model.data

每个item 都是由委托的paint()函数呈现的。
视图使用现成的QPainter对象调用这个函数,委托应该使用它来正确绘制项目的样式信息,以及模型中项目的索引:

这里就是 我们看到的每一个像素点 就是在这个函数里 paint 绘制出来的 根据model 里面的灰度值

咱们 一句一句看一下 这个函数



如果 像素点是选中状态 那么会填充 这个 矩形 显示蓝色

首先,通过使用样式选项的rect属性的最小维度来确定圆的最大可能半径。
利用所提供的模型索引 ,我们获得了图像中相关像素的亮度值。圆的半径是通过调整亮度以适应项目并从最大可能的半径中减去它来计算的。

这个地方就是求半径的 看不懂也没关系 这就是它的一种计算方式

写到这里刚才停电了 我以为没有了 吓我一跳 写了一个小时啊
还好有保存


这里就 保存画笔的信息
开启抗锯齿模式

还是 根据 有没有选中 像素点 画不同的颜色
上面是填充的 外部矩形框的颜色
这个是 里面 圆形的颜色 选中以后变为 白色
下面一句就是根据 半径画一个圆形

有的圆大 有的圆小 都是由 半径决定的 半径又是有 model 里面的 图像的灰度值决定的

结束

ok 这个文章就结束了 他这个 Example 就是用了自定义 model 和 delegate 来完成的
要理解的比较好 还是要 多看一下 MVD 找一些MVD 的资料看一下

Qt 用 MVD(model view delegate) 模式 把图片变为灰度像素点 [官方Example]相关推荐

  1. Qt学习笔记-----Model/View架构

    为了实现数据的存储和表现分离,Qt提供了Model/View架构,包括三个部分,分别是模型(Model),视图(View),委托(delegate). Model用于访问底层数据,也就是说为其他组件访 ...

  2. QT Basic 014 Model/View programming (模型、视图编程)

    前言:本文不是纯文本翻译,加入了对概念的理解,纯文本翻译,请看文后的一个链接. Model/View Programming Introduction to Model/View Programmin ...

  3. Qt学习笔记-----Model/View架构之自定义Model

    Model/View Framework中提供了模型model的抽象基类QAbstractItemModel, 如果需要自定义模型就需要继承这个类并且实现一些必要的函数. 此外,Qt中又提供了QAbs ...

  4. Qt Model/View/Delegate浅谈 - QAbstractListModel

    为什么80%的码农都做不了架构师?>>>    待补充... ##子类化 当子类化QAbstractListModel时,必须提供rowCount()和data()这2个函数的实现, ...

  5. Qt Model/View(MVD)模型分析

           最近在看Qt的Model/View Framework,在网上搜了搜,好像中文的除了几篇翻译没有什么有价值的文章.E文的除了Qt的官方介绍,其它文章也很少.看到一个老外在blog中写道M ...

  6. 第15.22节 PyQt(Python+Qt)入门学习:Model/View架构详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.简介 在PyQt和Qt中,Model/View架构是图形界面开发时用于管理数据和界面展现方式的关 ...

  7. Model/View模型视图

    catalog version model 函数 遍历 视图 当前项.选中项 Select SelectionMode SelectionBahavior QItemSelectionModel QT ...

  8. 初探 MVP(Model View Presenter) 设计模式

    刚刚转入C#开发不久,发现了一个类似于Java里的MVC模式的东东--MVP(Model View Presenter) 模式,个人感觉MVP模式真的和MVC差不多,MVC我这里就不解释了,着重讲讲M ...

  9. Qt Model/View编程介绍

    Qt中包含了一系列的项视图类,它们使用model/view的架构去管理数据之间的关系以及它们被展示给用户的方式.这种由这种架构引进的功能分离特性给了开发者很大的灵活性去自定义自己的展示方式,并且提供了 ...

最新文章

  1. 20CSS中的高级技巧
  2. openOffice word转pdf,pdf转图片优化版
  3. bootstrap42-Bootstrap 按钮组
  4. predis如何实现phpredis的pconnect方法
  5. 利用ES6的Generator语法实现自定义iterator
  6. 蓝桥杯 ADV-225 算法提高 9-2 文本加密
  7. iOS 给测试人员测试手机APP的四种方法:真机运行(略),打ipa包,(testFlighe)邮件,蒲公英(二)testflight
  8. [转]在WPF中打开网页方法总结
  9. 操作系统的启动与引导问题 BIOS、UEFI、MBR、GPT
  10. 2063:【例1.4】牛吃牧草
  11. 十、生产者消费者问题
  12. java连接数据库,jdbc四要素,jdbc六大步
  13. Sparse Merkle Tree
  14. 查找字符串fing()函数
  15. 林纳斯·托瓦兹 Linus Torvalds
  16. django html跳转页面跳转页面,django 常见页面的跳转,渲染,以及返回
  17. fileupload实现多文件批量上传
  18. Excel根据身份证号批量计算年龄+
  19. 使用mobiscroll实现级联效果
  20. 基于微信小程序的课程分享平台小程序

热门文章

  1. 计算机应用基础试卷分析报告,试卷分析计算机应用基础
  2. Java并发指南14:Java并发容器ConcurrentSkipListMap与CopyOnWriteArrayList
  3. 支付系统设计:绑卡、签约和身份验证(四)
  4. 计算机主板会自动切断电源是怎么回事,技嘉主板电脑,总自动关机,自动断电,怎么办呀?...
  5. 分享全国离线地图数据
  6. 深入jvm之对象如何进入老年代
  7. 2022危险化学品生产单位安全生产管理人员考试模拟100题及答案
  8. 股票 MACD指标的买入形态图解
  9. 全部汽车零部件更换周期 汽车零部件固定更换周期
  10. 国风 古风音乐 什么网站app比较好