Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 4064|回复: 2
打印 上一主题 下一主题

QTreeWidget修改行选中及滑过颜色

[复制链接]

1272

主题

2067

帖子

7962

积分

认证用户组

Rank: 5Rank: 5

积分
7962
跳转到指定楼层
楼主
发表于 2020-3-10 18:15:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
项目中使用QTreeWidget默认选中是蓝色的,我想改成其他颜色,代码是这样:
  1. ChartLeftTree::ChartLeftTree(QTreeWidget *parent) : QTreeWidget(parent)
  2. {
  3.      QStringList chartNames = { "bar","pie","line" };

  4.     int size = chartNames.size();
  5.     for(int i = 0; i < size; ++i){
  6.         QString chartName = chartNames.at(i);
  7.         QTreeWidgetItem * item = new QTreeWidgetItem(this);
  8.         item->setText(0,chartName);
  9.         item->setIcon(0,QIcon(CHART_ICON_PATH));
  10.     }
  11.     this->setHeaderHidden(true);
  12.     this->setStyleSheet("QTreeView::item::selected{background-color:green;} QTreeView::item::hover{background-color:green;}");

复制代码
但是显示结果是这样:






显然绿色没有完全覆盖,不能达到我想要的结果


网上提问了好多人都没有人回答,无奈自己搜吧,终于一篇文章给我了启发https://www.cnblogs.com/sunchaothu/p/9601298.html#qtreewidget


其中一句话给了我很大启发:TreeWidget的 checkbox 是由 indicator控制的, 展开/合起的是branch,于是我增加了branch的设置
  1. this->setStyleSheet("QTreeView::branch::hover{background-color:red;} QTreeView::item::hover{background-color:red;} QTreeView::branch::selected{background-color:green;} QTreeView::item::selected{background-color:green;} ");
复制代码
结果是这样



问题解决另外,再设置hover和selected的时候,顺序会影响显示效果,现在是前面设置hover后面设置的selected,当滑动到选中的条目时候,显示的是选中时的颜色(绿色),如果先设置selected,后设置hover,当滑动到选中的条目时候,显示的是滑动的颜色(红色)
————————————————
版权声明:本文为CSDN博主「wocan23」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wocan23/article/details/100986237


回复

使用道具 举报

1272

主题

2067

帖子

7962

积分

认证用户组

Rank: 5Rank: 5

积分
7962
沙发
 楼主| 发表于 2020-3-10 18:28:06 | 只看该作者

隐藏左侧的小箭头


rootIsDecorated : bool

treeView.setRootIsDecorated(False)

或者

    treeView.setStyleSheet( "QTreeView::branch {image:none;}" )

  设置item不同状态下显示背景色的代码,设置方法同上: 源码中设置:

treeWidget->setStyleSheet( "QTreeView::item:hover{background-color:rgb(0,255,0,50)}"
"QTreeView::item:selected{background-color:rgb(255,0,0,100)}" );
在样式设置界面,添加如下两句:
QTreeView::item:hover{background-color:rgb(0,255,0,50)}
QTreeView::item:selected{background-color:rgb(255,0,0,100)}


回复 支持 反对

使用道具 举报

1272

主题

2067

帖子

7962

积分

认证用户组

Rank: 5Rank: 5

积分
7962
板凳
 楼主| 发表于 2020-3-10 18:35:39 | 只看该作者
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变色的方案主要有以下方式

mousemove里面记住hover row,model的data函数里面返回对应BackgroundRole值(或者delegate里面绘制);leaveevent里面去掉背景色。
mousemove里面选中改行;leaveevent里面去掉选中。
qss里面设置。
https://zhuanlan.zhihu.com/p/73519691
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-11-26 06:20 , Processed in 0.058800 second(s), 18 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表