自己的一个工具里面用到了QTreeWidget,因为涉及到股票数据的显示,所以在Item上,不同列的含义不同,所以颜色也不一样,比如红色上涨,绿色下跌等。但是用了后,发现选中后,自己设置的颜色就无效了。
我的需求如下:
1、选中一行Item后,前景色保持原样,只多了个背景颜色,醒目一点;
2、窗口失去焦点时,不要把颜色改成了Inactive类型的颜色,还是保持原来的颜色,但是背景色可以变暗一点。
摸了半天,终于搞成了,我用了StyleSheet,所以还踩了坑,下面给出主要的做法吧,应该对QListWidget,QTrableWidget都类似。
首先,你需要定义前景色,比如第10列是根据正负显示不同的颜色,有类似这样的语句:
col = 10
if val > 0:
item.setData(col, Qt.ItemDataRole.ForegroundRole, QColor(0xFF0000))
elif val < 0:
item.setData(col, Qt.ItemDataRole.ForegroundRole, QColor(0x00FF00))
else:
item.setData(col, Qt.ItemDataRole.ForegroundRole, QColor(0xFFFFFF))
然后,你需要重载 QStyledItemDelegate,如果没用到StyleSheet就用 QItemDelegate(我一开始没注意,照网上的用的这个,发现没有任何效果),重载函数一样。
class MyDelegate(QtWidgets.QStyledItemDelegate):
'''重载后,绘制Item的时候,使文字的前景色保持不变'''
def paint(self, painter, option, index):
if option.state & QtWidgets.QStyle.StateFlag.State_Selected: # 只针对选中了的行
# 根据窗口状态,获取ColorGroup
cg = (
QtGui.QPalette.ColorGroup.Normal
if option.state & QtWidgets.QStyle.StateFlag.State_Enabled
else QtGui.QPalette.ColorGroup.Disabled
)
# 对失去焦点重新计算cg
if cg == QtGui.QPalette.ColorGroup.Normal and not (option.state & QtWidgets.QStyle.StateFlag.State_Active):
cg = QtGui.QPalette.ColorGroup.Inactive
# 记录先前的高亮颜色
old_c = option.palette.color(QtGui.QPalette.ColorRole.HighlightedText)
# 提取程序自己设置的前景色
itemForegroundColor = index.data(Qt.ItemDataRole.ForegroundRole)
if itemForegroundColor is not None:
c = itemForegroundColor
else: # 如果没设置前景色的item,直接使用文本色
c = option.palette.color(QtGui.QPalette.ColorRole.Text)
# 修改option中的高亮颜色并绘制
option.palette.setColor(cg, QtGui.QPalette.ColorRole.HighlightedText, c)
super().paint(painter, option, index)
# 恢复先前的颜色
option.palette.setColor(cg, QtGui.QPalette.ColorRole.HighlightedText, old_c)
else: # 没选中的默认绘制
super().paint(painter, option, index)
然后,在QTreeWidget初始化的地方,加一行:
treeWidget = QTreeWidget()
# ...
treeWidget.setItemDelegate(MyDelegate())
把我的style也列一下:
QTreeWidget {
show-decoration-selected: 1;
outline: none;
}
QHeaderView::section {
background-color:black;
border:1px solid #3f3f3f;
text-align:center;
qproperty-defaultAlignment: AlignHCenter;
}
QTreeWidget::item {
border: 1px solid #0f0f0f;
margin:0px;
padding:2px;
qproperty-defaultAlignment: AlignHCenter;
}
QTreeWidget::item:selected:active {
background-color:#000064;
}
QTreeWidget::item:selected:!active {
background-color:#000032;
}
看看效果图:
选中时:
失去焦点后:
仅供参考 !