2
self.grid.setStyleSheet("QTableWidget::item::selected { background-color:#F9F6F5 ; color:black;  
border: 3px solid black; }")

currently i'm using styleSheet for my qtablewidget background when i select an item it changes that cell's background like this which is what i want

but when i start editing it is back to default settings like this and i dont know which keyword should i use instead of 'item::selected' or if it even exists

FurkanOzcelik
  • 75
  • 1
  • 7

1 Answers1

2

You can use the descendant css selector, which can be used to specify the style for a widget that is descendant of another (it could be a direct child, a "grandchild", etc).

Editing of item views is usually done with a QLineEdit if the item has string values, the solution is to use QTableWidget QLineEdit, and since the styling is going to be the same, you can also concatenate the selectors with commas:

self.grid.setStyleSheet('''
    QTableWidget::item::selected, QTableWidget QLineEdit { 
        background-color: #F9F6F5; 
        color: black; 
        border: 3px solid black; 
    }
''')

Note that you need the descendant selector, not the child selector (parent > child) which is for direct children only: the editor of an item view is not a direct child of the view, as an item view has the following hierarchy:

item view -> viewport (the scrollable contents) -> editor

If you set the stylesheet on the table widget, the descendant selector is not even required, since it's automatically applied to all widgets that are children of the widget on which the css is applied.

If other data types are used for the Qt.DisplayRole (or, to be more precise, the Qt.EditRole), you should use the relative widget depending on the type: for example, if you set the value as an integer, QSpinBox will be used, so the selector will be QTableWidget QSpinBox.

Besides strings and bool (which uses QComboBox), all the other standard editing widgets are subclasses of QAbstractSpinBox, so you can just use that parent class instead (in the following example I'm assuming that self.grid is a QTableWidget):

    self.grid.setStyleSheet('''
        QTableWidget::item::selected, 
        QLineEdit, QComboBox, QAbstractSpinBox {
            ...
        }
''')

If the stylesheet is set on a parent (for example, the main window, or even the whole application), you'll still need the descendant selector:

class MyMainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        # ...
        self.setStyleSheet('''
            QTableWidget::item::selected, 
            QTableWidget QLineEdit, 
            QTableWidget QComboBox, 
            QTableWidget QAbstractSpinBox {
                ...
            }
        ''')
musicamante
  • 41,230
  • 6
  • 33
  • 58
  • 1
    thank you, where can i learn such things, i didnt see any documentation mentioning about Qtablewidget using Qlineedit or i've learned keywords such as item::selected, border... on different websites – FurkanOzcelik Sep 07 '20 at 16:03
  • 1
    All editable item views (QColumnView, QTableView, QTreeView, QListView and their subclasses QTableWidget, QTreeWidget and QListWidget) create an editor depending on the data type of the index for the `Qt.EditRole` (usually the same as the `Qt.DisplayRole`): QLineEdit for strings, QSpinBox for integers, QDoubleSpinBox for floats, QDateEdit for dates, etc. This obviously means that if you set different types of data for table widget items, you'll have to add the corresponding editing widget classes to the css. – musicamante Sep 07 '20 at 17:29
  • 1
    The standard editing widgets provided as default are listed in the [QItemEditorFactory](https://doc.qt.io/qt-5/qitemeditorfactory.html#standard-editing-widgets) documentation. – musicamante Sep 07 '20 at 17:37