使用代理的方式在qtableview中实时的局部刷新图片(该方法同样适用于qtreeview)

 

  1. 目的:加快进入界面时候加快图片加载的速度,每一行的图片根据数据的变化而显示不同的图片样式,数据变化则图片根据数据而变化。(注意是根据某一行或者某一列的数据改变)。只是一种实现方法,不讲原理。
  2. 方法说明

(1) 一般来说如果数据量不大使用视图自带的函数setIndexWidget(const QModelIndex & index, QWidget * widget)可以添加一些自定义控件之类的。但是如果一个界面拥有大量的图片数据的时候,再使用该方法效率及其低下,最直观的一点就是第一次进入该界面的时候会感觉到明显的延迟。(之前测试2040张图片,debug模式下第一次加载界面将近2s,用代理的方法200ms都不到起码视觉上几乎感觉不到延迟,release模式下更快,这里还有数据库读取也算上了,数据库当时只读取了一次大概50ms左右,速度上来讲10倍的差距)。

(2) 该方法是在代理提供的默认方法上面添加的改进方案。正常来讲一般都是直接代理一整行或者一整列。(网上方案很多这里不予举例)

(3) 该方案主要利用的是视图/模型中自带的信号dataChanged触发对应单元格的重绘功能。

(4) 该方案只提供核心代码和思路。

  1. 思路/及代码说明

(1) 代理类

代理头文件

代理声明

代理头文件实现:

继承QStyledItemDelegate并重写paint,editorEvent函数。

代理实现

 

 

 

 

 

代理实现

① 代码说明

② 改代码实现的代理效果是一个button按钮。

③ StationsStatus paint中的stationStatus类是一个单例的概念,他记录了表格中对应行的当前状态。这个信息状态可以直接存储在QStandardItemdata中,但是我这边有多个界面都用到了这个信息所以直接抽象出来了。

④ 注释掉的代码是关于按钮的按下,悬浮(hover)等效果,我这边不需要就屏蔽掉了,如果想要对应效果开启这部分代码,并在下方写上对应的qss或者直接在判断分支里面重新手动绘制想要的效果都可以。这部分网上也有很多不做多余解释。

⑤ editorEvent中在鼠标释放的时候触发了对应的按钮信号,其实并不是按钮发出的信号,而是鼠标在单元格内规定的范围之按下了按钮所以触发了对应的效果。相当于模拟QPushButtonclick信号。如果一个单元格之内想放入多个按钮的话,并实现对应的信号可以参考如下方法。

⑥ 多按钮参考网址: https://www.codeleading.com/article/55535964738/

⑦ 这里已经是核心代码了,剩下的就是当状态改变的时候如果触发对应单元格的重绘事件,如开头所说,当对应的dataChange(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector<int> & roles = QVector<int> ())被触发的时候,就会触发对应的重绘功能。

[]该代理实现的是类似于开关的功能,状态改变时会有不同的图片显示,如果只是单纯的向放入图片不要其他功能的话可以在这里放入一个QLabel/Qwidget...editorEvente中不要触发相应信号即可,但是代码会有些许不同,网上找两个不同代理的实例看一下就明白了.

(2) 加载代理类

① 实现代码

 

加载代理类

② 如果代理中放入的是QPushButton并想实现对应的hover效果,则还要开启对应表格的鼠标追踪事件,这个对我们的功能来说可有可无。想要这个效果的话可以开启。

ui->treeStation->setMouseTracking(true);

树或者表都一样,按照如上方法可开启对应鼠标追踪事件。

③ SlotConnectStation 点击按钮触发事件实现

 

按钮点击事件触发

代码说明:通过单例获取当前按钮状态,单击按钮之后如果不需要执行一些事务可以直接把slotStationStatusChange 的代码放入这里,直接修改对应图片就行。这里的socket可以了理解为我自己的事务类,他会处理对应点击事件所要执行的事务。如上没有事务直接改图片就成。

④ slotStationStatusChange 根据状态修改对应图片方法

 

根据状态切换图片

slotStationStatusChange 这个函数在我的执行逻辑中只有状态被改变的才会触发,也就是说这个被触发了当前一定切换了状态。

核心代码就是:statusItem->setData(status,Qt::UserRole);只要data中有对应角色的内容被修改了,dataChange就会被触发,进而触发对应单元格的paint函数重新绘制对应图片。

⑤ slotSendConnectCmdError 修改状态失败(我们这里并不需要对应的功能,但是代码还是贴上)

 

错误提示功能

该函数在我这里只有状态切换失败之后会被触发。这里的功能可以理解为QMessageBox,一个提示效果。

核心代码就是代理类的实现,图片实时切换功能的实现就是通过状态信息和代理重绘配合,说白了就是手动控制器这个图片是否切换。

posted @ 2021-11-25 18:47  SmartGame  阅读(958)  评论(0编辑  收藏  举报