Disable custome delegate listview item selected border
Unsolved
Qt for Python
-
Hi, I am use PySide6 build a simple application with qt: 6.2.4.
And there is auto append item border I cann't disable or remove it.
and when selected a item, the painter draw rect also have a border.
How to disable the default behavior? thanks!
Here is my code test:#!/usr/bin/env python3 # encoding: utf-8 import sys from PySide6.QtCore import QAbstractListModel, QModelIndex, Qt, QSize, QRect from PySide6.QtGui import QPainter, QColor, QPen from PySide6.QtWidgets import QApplication, QMainWindow, QListView, QStyledItemDelegate, QStyleOptionViewItem, QStyle, \ QWidget class ListModel(QAbstractListModel): def __init__(self, *args, **kwargs): super(ListModel, self).__init__(*args, **kwargs) self.listData = ['Name01', 'Name02', 'Name03', 'Name04', 'Name05', 'Name06', 'Name07', 'Name08'] def rowCount(self, parent: QModelIndex) -> int: return len(self.listData) def data(self, index: QModelIndex, role: int) -> str: if Qt.DisplayRole == role: return self.listData[index.row()] class ListViewItemDelegate(QStyledItemDelegate): def __init__(self, icon_size: QSize = QSize(160, 160), *args, **kwargs): super(ListViewItemDelegate, self).__init__(*args, **kwargs) self.icon_size = icon_size self.text_size = QSize(icon_size.width(), 20) def paint(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex) -> None: painter.save() text = index.data(Qt.DisplayRole) if option.state & QStyle.State_HasFocus: option.state = option.state ^ QStyle.State_HasFocus # Draw background if option.state & QStyle.State_Selected: pen = QPen(QColor(153, 209, 255)) pen.setWidth(4) painter.setPen(pen) painter.setBrush(QColor(204, 232, 255)) else: if option.state & QStyle.State_MouseOver: pen = QPen(QColor(229, 243, 255)) pen.setWidth(4) painter.setPen(pen) painter.setBrush(QColor(229, 243, 255)) else: painter.setPen(Qt.GlobalColor.white) painter.setBrush(Qt.GlobalColor.white) painter.drawRect(option.rect) # Draw Icon # Reset pan to disable the icon border, Thanks @SGaist, but the item still append a border on outline. painter.setPen(Qt.GlobalColor.transparent) painter.setBrush(Qt.GlobalColor.gray) painter.drawRect(QRect(option.rect.x() + 10, option.rect.y() + 10, self.icon_size.width() - 20, self.icon_size.height() - 20)) # Draw name text text_rect = QRect( option.rect.x(), option.rect.y() + self.icon_size.height(), self.icon_size.width(), self.text_size.height() ) painter.setPen(Qt.GlobalColor.black) painter.drawText(text_rect, Qt.TextWordWrap | Qt.AlignCenter, text) painter.restore() # super(ListViewItemDelegate, self).paint(painter, option, index) def sizeHint(self, option: QStyleOptionViewItem, index: QModelIndex) -> QSize: return QSize(self.text_size.width(), self.icon_size.height() + self.text_size.height()) def createEditor(self, parent: QWidget, option: QStyleOptionViewItem, index: QModelIndex): return False class ListView(QListView): def __init__(self, *args, **kwargs): super(ListView, self).__init__(*args, **kwargs) self.setModel(ListModel()) self.setItemDelegate(ListViewItemDelegate(icon_size=QSize(120, 120))) self.setDragEnabled(False) self.setAcceptDrops(False) self.setEditTriggers(QListView.NoEditTriggers) self.setMovement(QListView.Movement.Static) self.setViewMode(QListView.ViewMode.IconMode) self.setWordWrap(True) self.setSpacing(20) self.setResizeMode(QListView.ResizeMode.Adjust) self.setObjectName("test") self.setStyleSheet(""" #test { border: 1px solid red; outline: none; } #test::item { border: none; } #test::item::focus { border: none; } """) class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.resize(600, 400) self.setWindowTitle("ListView Sample") self.setCentralWidget(ListView()) if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())
I also have screen record the effect to show it.
-
Hi,
Isn't that because you don't reset the pen width when you are done drawing with it. ?
-
You need to reset the pen width to 1. Calling your painter's
setPen
with just a color won't change the width of the underlying pen.