61373f0b66d6cc1773edcc2233e84dc8.png

model/view模型是QT为提高界面UI性能引入的一种设计模式,在开发数据量很多的表格或树状结构UI时候,相较于传统tablewidget/treewidget有很大的性能提升。model定义了一些访问数据的接口,data为其核心函数,定义了根据不同角色来解析数据展示UI,故数据变化的时候UI会动态刷新。view是界面UI视图,可以通过相关接口来设置UI显示的一些特性,并通过setomodel接口与对应model进行绑定,以及setItemDelegate与delegate绑定。delegate主要是用来自定义UI的绘制,虽然model里面可以指定UI的展示形式,但是一般设计师设计的界面很难单纯用model指定的ui形式来展示,通常都会结合delegate来绘制。

最近做的一个需求涉及到树状和表格型UI的界面绘制,采用的便是QT model/view开发模型,设计师要求树状或表格UI展示上能够支持鼠标Hover变色,在开发过程中尝试了诸多方案,踩了不少坑,主要遇到的问题有1.多列数据在鼠标滑动较快的时候颜色变化不会一致。2.treeview的branch(收缩箭头)和item项颜色不一致,收缩箭头的样式调整 3.mac环境下hover色和selection颜色不一致导致的显示不和谐。4.使用selection来模拟hover变色时候鼠标滑动至tableview最下方会导致一直向下滚动的奇怪现象。本文对hover变色的方案做个记录并总结。

tableview和treeview的hover变色方案一般可以通过代码里面相关逻辑来实现,或者通过qss来修改,qss接触的少,修改起来很难达到理想效果。tableview和treeview的hover变色方案修改代码逻辑实现的原理一致,常规方案就是view在收到mousemove事件时候记录hover row,然后在mode的data函数里面返回对应BackgroundRole的值,或者在delegate的paint函数里面根据前面记住的hover row做相应绘制。在delegate里面绘制也可以不用通过mosemove来记录hover row而是直接根据根据QStyleOptionViewItem项的state为 QStyle::State_MouseOver或QStyle::State_Selected来绘制整个item项的背景色。去掉背景色则要在leaveevent的事件函数里面做更新。tableview用前面的常规方案基本没什么问题。但是treeview用前面的方案时伸缩按钮不会变色,而且多列情况下颜色变化不会一致。最后寻求的方案是对treeview用selection来模拟hover变色,具体实现是设置选择选中行为及模式,hover的时候不返回颜色或绘制而是选中当前行。这种方案在win下是没用问题的 但是在mac下branch(伸缩按钮)和item项的颜色还是不一致,这个主要原因是branch显示的hover色 而item是显示选中色。为解决这个问题,需在delegate的绘制函数里面区分mac环境 并根据QStyleOptionViewItem项的state为 QStyle::State_MouseOver或QStyle::State_Selected来设置QStyleOptionViewItem调色板中的画刷颜色,如果要修改branch的图标则只能在qss里面设置相应图标换图,若要修改其size则需要在treeview里面调用setIndentation接口。

其他:在对tableview里面用选中来模拟变色的时候发现个很诡异的现象,鼠标放至tableview可显示的最后一行,scrollbar会一直向下滚动。经分析方案是用选中来模拟变色,鼠标hover到最下面一行的时候会选中该行,而又由于tableview的高度让最后一行不会完整显示,故每选中一次它会向上跳动一下会导致前面所说现象。这个bug可以通过调整tableview的高度或者只能用常规方案来hover变色不能用选中来模拟。

总结:hover变色的方案主要有以下方式

  1. mousemove里面记住hover row,model的data函数里面返回对应BackgroundRole值(或者delegate里面绘制);leaveevent里面去掉背景色。
  2. mousemove里面选中改行;leaveevent里面去掉选中。
  3. qss里面设置。
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐