I'm developing a small application that compares *.xls and *.xlsx files using PyQt4.
Here is what the comparison window looks like. The row is highlighted in light red, while the cell text has a bright red color.
When I select the row by clicking on it all the red highlighting is gone.
Is there any way, in this situation, to make the cells that are marked with red to stay that way ?
I'm using QtCore.QAbstractTableModel for each QtGui.QTableView
def data(self, index, role):
"""
Updating tableView data
"""
#########################################################
# Data role -> Updating cell contents #
#########################################################
if role == QtCore.Qt.DisplayRole:
row = index.row()
if 0 <= row < self.rowCount():
column = index.column()
if 0 <= column < self.columnCount():
return self._data[row][column]
#########################################################
# Background role -> Updating row color #
#########################################################
if role == QtCore.Qt.BackgroundRole and index.row() in self._marked_rows:
customColor = QtGui.QColor(255, 204, 204)
return QtCore.QVariant(QtGui.QBrush(customColor))
#########################################################
# TextColorRole role -> Updating cell text color #
#########################################################
if role == QtCore.Qt.ForegroundRole:
if str(index.row()) + ':' + str(index.column()) in self._marked_cells:
return QtCore.QVariant(QtGui.QColor(QtCore.Qt.red))
After some searches I tried using QtGui.QStyledItemDelegate. Now the text keeps its color, but there is no highlighting and I do not know how to keep the row's light red color.
class TextColorDelegate(QtGui.QStyledItemDelegate):
def __init__(self, cells, parent = None):
QtGui.QStyledItemDelegate.__init__(self, parent)
self.cells = cells
def paint(self, painter, option, index):
painter.save()
value = index.data(QtCore.Qt.DisplayRole)
if value.isValid():
text = value.toString()
if str(index.row()) + ':' + str(index.column()) in self.cells:
painter.setPen(QtGui.QPen(QtCore.Qt.red))
painter.drawText(option.rect, QtCore.Qt.AlignVCenter, text)
else:
painter.setPen(QtGui.QPen(QtCore.Qt.black))
painter.drawText(option.rect, QtCore.Qt.AlignVCenter, text)
painter.restore()
self.model_1 = TableModel(_data_1,
columns_string,
_markedRows_1,
_markedCells_1,
self.appPath,
self.tableView_1)
delegate_1 = TextColorDelegate(_markedCells_1, self)
self.tableView_1.setModel(self.model_1)
self.tableView_1.setItemDelegate(delegate_1)
Is there any way to target those specific cells and keep the row highlighting ?
I managed to find a solution on my own. Maybe a more simple one is possible, but it works.
class TextColorDelegate(QtGui.QStyledItemDelegate):
"""
Delegate used for changing text color and highlighting behaviour
"""
def __init__(self, cells, parent = None):
"""
Object initialization
cells - marked cells that have different content
"""
QtGui.QStyledItemDelegate.__init__(self, parent)
self.cells = cells
def paint(self, painter, option, index):
"""
Painter function used for overriding display behaviour
"""
painter.save()
displayText = index.data(QtCore.Qt.DisplayRole)
backgroudColor = index.data(QtCore.Qt.BackgroundColorRole)
customColor = QtGui.QColor(255, 204, 204)
blackColor = QtCore.Qt.black
yellowColor = QtCore.Qt.yellow
redColor = QtCore.Qt.red
backgroundFlag = backgroudColor.isValid()
textFlag = displayText.isValid()
textContent = displayText.toString()
if backgroudColor.isValid():
###################################################################
# Evaluating rows with differences #
# Adjusting background and text color depending on QStyleState #
###################################################################
painter.fillRect(option.rect, customColor) #set row background color
if (option.state & QtGui.QStyle.State_Selected):
painter.fillRect(option.rect, option.palette.highlight())
color_to_set = yellowColor if ( str( index.row() ) + ':' + str( index.column() ) ) in self.cells else blackColor
else:
color_to_set = redColor if ( str( index.row() ) + ':' + str( index.column() ) ) in self.cells else blackColor
###################################################################
# Evaluating rows with no differences #
# Adjusting background and text color depending on QStyleState #
###################################################################
else:
if (option.state & QtGui.QStyle.State_Selected) : painter.fillRect(option.rect, option.palette.highlight())
color_to_set = blackColor
if textFlag:
painter.setPen(QtGui.QPen(color_to_set))
painter.drawText(option.rect, QtCore.Qt.AlignVCenter, textContent)
painter.restore()
Now the highlighting works.
https://i.sstatic.net/9r4gq.jpg
https://i.sstatic.net/Nruvr.jpg