Mystic_Force
Mystic_Force

Reputation: 263

change the background color of a cell in a QTableWidget element when the content is edited

I am designing a QTableWidget element in which I need to change the default behavior of a cell when it is edited.

What I need to achieve is that the background of the cell does not change to white, but rather that I can change that background to another color

This is my style sheet code

QTableWidget{
border:none;
border-left:1px solid #b0b9cf;
border-bottom: 1px solid #b0b9cf;
border-right:1px solid #b0b9cf;
selection-color:red;
selection-background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 0, 0, 0), stop:1 rgba(255, 255, 255, 0));
}
QHeaderView::section:horizontal{
background:#3d4454;
color:white;
border:0px;
border-bottom:2px solid #b0b9cf;
boder-left: 1px solid #b0b9cf;
border-right:1px solid #b0b9cf;
}
QTableWidget::item:selected{
border:1px solid blue;
}

QTableWidget::item:alternate{
background:red;
color:white;
}

enter image description here

The section indicated in the image represents the cell that is in text editing mode and changes its background color to white. The result that I expect to obtain is that the background and text color does not change when it enters editing mode

In other words, in this case, keep the red background and the white text color

Thank you and I hope you can help me

Upvotes: 0

Views: 731

Answers (1)

musicamante
musicamante

Reputation: 48529

It's not possible to do it dynamically.

The problem is that QSS (Qt Style Sheets) completely override the underlying style and drawing of complex widgets and their sub-elements is completely done internally by the (private) QStyleSheetStyle.

Most importantly, the alternate row color is only intended as a visual aid, because it's scope is usability, not data based customization: the alternate color should always be related to the base color, because the text color should be the same and readable in both cases.

While QSS allow such customization, advanced usage is limited.

You could theoretically work around the background by using a custom delegate and set a transparent background for the editor, but this would show the current content of the cell also, so it's not a valid option.

There is no direct and easy way to know the actual background/text color of the cell if it's set by stylesheets. The only solution is to use hardcoded colors and set them for the editor:

class Delegate(QStyledItemDelegate):
    def createEditor(self, parent, option, index):
        editor = super().createEditor(parent, option, index)
        if index.row() & 1:
            editor.setStyleSheet('''
                {} {{ background: red; color: white;}}
            '''.format(editor.__class__.__name__))
        return editor

# ...
tableWidget.setItemDelegate(Delegate(tableWidget))

Notes:

  • remember that QSS work very similar to CSS:
    • when even a single, main property of a complex widget is styled, you need to set all the other main properties of that widget;
    • properties are inherited if the QSS can be applied for the target, that's why it's always important to use proper selectors for containers and complex widgets, as I did above (if I used plain properties, the context menu would have used those colors too);
  • instead of using stylesheets for items, you could consider using a custom delegate that would alter the palette before calling the QStyle drawing within the delegate's paint() function; while this would still need hardcoded colors, they could be accessed dynamically more easily;
  • QSS are very powerful, but also quite "delicate"; there is no direct way to know every aspect they set, which limits the read access to their rules (see this related answer): most importantly, we can only indirectly access a few color properties for the "main" widget, but any sub-control/state is totally based on the parser and completely internal;
  • your QSS has a typo (boder-left should be border-left);

Upvotes: 1

Related Questions