I want to customize how the highlight looks when an item is selected in the table, specifically change the area that is highlighted when an item is selected. However, for some reason this code, which has previously worked in another project of mine, is now not working as expected.
Previously working MRE:
from PySide6 import QtCore as qtc
from PySide6 import QtGui as qtg
from PySide6 import QtWidgets as qtw
class ListItemsDelegate(qtw.QStyledItemDelegate):
def paint(self, painter: qtg.QPainter, option: qtw.QStyleOptionViewItem, index: qtc.QModelIndex) -> None:
if option.state & qtw.QStyle.StateFlag.State_Selected:
painter.fillRect(
qtc.QRect(
option.rect.left(),
option.rect.top(),
20,
option.rect.height()
),
qtc.Qt.GlobalColor.blue,
)
option.state &= ~qtw.QStyle.StateFlag.State_Selected
option.state &= ~qtw.QStyle.StateFlag.State_HasFocus
painter.drawText(option.rect.topLeft(), "text")
app = qtw.QApplication()
model = qtc.QStringListModel([1, 2, 3])
view = qtw.QListView()
view.setModel(model)
view.setItemDelegate(ListItemsDelegate())
view.show()
app.exec()
Previously working image:
Now not working MRE:
from PySide6 import QtCore as qtc
from PySide6 import QtGui as qtg
from PySide6 import QtWidgets as qtw
class TableItemsDelegate(qtw.QStyledItemDelegate):
def paint(self, painter: qtg.QPainter, option: qtw.QStyleOptionViewItem, index: qtc.QModelIndex) -> None:
if option.state & qtw.QStyle.StateFlag.State_Selected:
highlight_rect = qtc.QRect(option.rect)
highlight_rect.adjust(20, 20, -20, -20)
painter.fillRect(
highlight_rect,
qtc.Qt.GlobalColor.blue,
)
option.state &= ~qtw.QStyle.StateFlag.State_Selected
option.state &= ~qtw.QStyle.StateFlag.State_HasFocus
painter.drawText(option.rect.topLeft(), "text")
class TableModel(qtc.QAbstractTableModel):
def data(self, *args) -> int:
return 1
def rowCount(self, *args) -> int:
return 5
def columnCount(self, *args) -> int:
return 5
app = qtw.QApplication()
view = qtw.QTableView()
view.setModel(TableModel())
view.setItemDelegate(TableItemsDelegate())
view.show()
app.exec()
Not working image:
They're both quite literally the same code yet I only get the custom highlight with the QListView
, while I get both the custom highlight and the default highlight with QTableView
, why would that be?
Created a custom style and applied that to the QTableView
object:
class GridViewStyle(qtw.QProxyStyle):
# To hide default selection highlight.
def drawPrimitive(self, element, option, painter, widget=None) -> None:
# Check if selected:
if option.state & qtw.QStyle.StateFlag.State_Selected:
# if selected, remove the State_Selected StateFlag,
option.state &= ~qtw.QStyle.StateFlag.State_Selected
# drawPrimitive call now does everything it does, except draw selection highlight,
super().drawPrimitive(element, option, painter)
# re-add State_Selected StateFlag so paint() in delegate can use it.
option.state |= qtw.QStyle.StateFlag.State_Selected
else:
super().drawPrimitive(element, option, painter)