QTreeWidget QSS 分析 样式和自定义行样式
QTreeWidget 样式表
一、前言最近项目使用QTreeWidget 绘制Item遇到一些问题和当前应该怎么解决进行回顾。
问题列表
在下面样式设置中遇到几个经典问题:
- 行背景颜色问题(默认背景、选中背景、父子不同背景);
- 设置行间距;
- 设置样式圆角;
一、行背景颜色问题(默认背景、选中背景、父子不同背景);
设置背景行的时候首先要知道QTreewidget继承与QTreeView,所以QTreeView也会影响QTreewidget背景。设置QTreeWidget整体背景是。
QTreeWidget{
outline:0px;
background: #090909;
color:#F4EDFF;
selection-background-color: transparent;
}
行背景设置:
QTreeWidget::item{
margin-top:1px;
margin-bottom:1px;
border:none;
background: #151514;
color:#F4EDFF;
height:20px;
padding:5px;
font-size:14px;
}
这样设置并没有在整行更改背景而是只是子item显示的:
前面的行颜色没有显示完整所以我们需要更改:
QTreeWidget::branch
{
background: #151514;
margin-top:1px;
margin-bottom:1px;
}
这样整行都是一个背景了正如选中颜色背景同样需要设置branch:
QTreeWidget::item:selected, QTreeWidget::branch:selected{
border-left-color:transparent;
border-right-color:transparent;
border-top-color:transparent;
border-bottom-color:transparent;
background-color:rgb(88,56,101);
}
设置展开图标时需要:
QTreeWidget::branch:closed:has-children:!has-siblings,
QTreeWidget::branch:closed:has-children:has-siblings {
border-image: none;
image: url(:/skins/CommonCtrl/resource/List_arrow_close_2x.png);
}
QTreeWidget::branch:open:has-children:!has-siblings,
QTreeWidget::branch:open:has-children:has-siblings {
border-image: none;
image: url(:/skins/CommonCtrl/resource/List_arrow_open_2x.png);
}
当有特殊需求比如需要父子显示不同颜色时候我想的是:
QTreeWidget::item::has-children{
border:none;
background: #2A2A2A;
color:#EAEAEA;
}
但是实际却是:
是的我们发现父Item前面的branch并没有改变同样和我们设置item颜色一样只是item变,那么我们继续用设置:
QTreeWidget::branch:has-children
{
background: #2A2A2A;
}
发现最前面的父item确实整行都是修改但是下一个的item却前面没有设置成功。没错我就是卡在这里没有办法将整行qss,前面支出来的感觉不是属于qtreewidget的branch为两个。
所以我选择重写QTreeWidget::drawRow(painter, opt, index);
void CPXAnimaTree::drawRow(QPainter* painter, const QStyleOptionViewItem& options, const QModelIndex& index) const
{
QStyleOptionViewItem opt(options);
painter->setRenderHint(QPainter::Antialiasing);
QPainterPath path;
path.addRect(options.rect);
auto value = index.child(0,index.column());
QColor col_parent("#2A2A2A");
QColor col_child("#1F1F1F");
if (value.isValid())//是否有子节点可用
{
painter->fillPath(path,col_parent);
}
else
{
painter->fillPath(path,col_child);
}
QTreeWidget::drawRow(painter, opt, index);
}
这样就可以判断将整行都设置为一种颜色但是因为branch显示在上面所以我们需要设置他为透明:
QTreeWidget::branch{
background: transparent;
margin-left:0px;
}
同理其他item都要设置为透明。
二、设置行间距
从上面的设置可以看出来qss也是可以设置行间距的:
QTreeWidget::item{
margin-top:1px;
margin-bottom:1px;
}
可以看出上下1px间距为2px
同理可以重写QTreeWidget::drawRow(painter, opt, index);同样实现:
void CPXAnimaTree::drawRow(QPainter* painter, const QStyleOptionViewItem& options, const QModelIndex& index) const
{
QStyleOptionViewItem opt(options);
opt.rect.adjust(0 ,1, 0, 0);
QTreeWidget::drawRow(painter, opt, index);
}
我们修改opt的rect同样实现行间距。
三、设置样式圆角
首先我也是想用qss实现圆角发现还是和父branch出现现象一样。
QTreeWidget::item{
margin-top:1px;
margin-bottom:1px;
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
}
QTreeWidget::branch{
background: transparent;
margin-left:0px;
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
}
出现:
他多个branch下也显示圆角。修改branch会同步修改这一层的"几个"branch。所以我就放弃了还是重写实现圆角。
void CPXAnimaTree::drawRow(QPainter* painter, const QStyleOptionViewItem& options, const QModelIndex& index) const
{
QStyleOptionViewItem opt(options);
opt.rect.adjust(0 , 2, 0, 0); //修改间距
painter->setRenderHint(QPainter::Antialiasing);
QPainterPath path;
path.addRoundedRect(options.rect.x(), options.rect.y(), options.rect.width(), options.rect.height()- 2, 2, 2); //添加圆角矩形到路径中
auto value = index.child(0,index.column());
QColor col_parent("#2A2A2A"); //父子不同背景颜色
QColor col_child("#1F1F1F");
auto item = this->itemFromIndex(index);
if (item)
{
if (item->isSelected())//修改选中时的颜色
{
ol_child = QColor(89, 56, 102, 100);//QColor((89, 56, 102));
col_parent = QColor(89, 56, 102, 100);
}
}
if (value.isValid())
{
painter->fillPath(path,col_parent);
}
else
{
painter->fillPath(path,col_child);
}
QTreeWidget::drawRow(painter, opt, index);
}
同样的需要将item和branch和branch:!has-children:has-siblings:adjoins-item都设置为透明显示因为他们都是显示在draw上面。
这样就完成相关需求,但是不明白的一点就是qss是否是可以将branch分成修改,这点需要下来查一下资料或者有大佬回帖一下