Question

I have a custom QTableView and a custom QAbstractTableModel. The view only allows single selections. I'm trying to customize the background color of the selected cell under some conditions with no success. I expected to do it by combining the data method of the model with the selectionChanged method of the view. For instance, let's suppose I want to change the color of the selected cell when it matches a given row. My code for the selectionChanged method is:

def selectionChanged(self, selected, deselected):
    #QtGui.QTableView.selectionChanged(self, selected, deselected)
    # Get the selected indexes from the QItemSelection object
    selection = selected.indexes()
    # Let the model track the selected cell
    self.tmodel.selected_index = selection[0]
    # Desperately try to make it work
    self.tmodel.dataChanged.emit(selection[0], selection[0])
    self.viewport().update()

My simplified code for the data method is:

def data(self, index, role=QtCore.Qt.DisplayRole):
    if not index.isValid():
        return None
    # Some code here dealing with several roles
    if role == QtCore.Qt.DisplayRole:
    ...
    elif role == QtCore.Qt.BackgroundRole:
        if ((index == self.selected_index) and (index.row() == 3)):
            print '++++ displaying selected'
            return QtGui.QColor(QtCore.Qt.yellow)
        else:
            return QtGui.QColor(QtCore.Qt.green)
    else:
        return None

The non selected cells have a green background as expected. The strange thing is that when I select a cell in the matching row, the message ++++ displaying selected is printed but the selected cell has the system default background instead of a yellow one. I must be missing something important/obvious here but I've no idea about what it is.

Update

I know I can achieve my goal using a custom delegate and implementing its paint method but I'd like to know why the code above fails.

Was it helpful?

Solution

OK, I think I got it. The think is that the default delegate uses the values returned by data in order to render the table cells. Accordingly to the docs:

By supplying appropriate item data for each role, models can provide hints to views and delegates about how items should be presented to the user. Different kinds of views have the freedom to interpret or ignore this information as required.

So the behavior described in the question is explained as follow: non selected cells are rendered in the standard way by the default delegate which implies the color returned by data method will be used. However, selected cell are rendered in a different way by the default delegate, the value returned by data method is ignored in this case because it uses the background provided by the system style.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top