Issue
I want to draw a second icon in a single column, on the right side of the standard painting event of that column. You can see below I draw a red icon on the far right side of the items in column 3. How would I go about doing this using a QItemDelegate? I would prefer the default paint even still happens in order to pain the decoration role and display role text.
import os, sys, pprint
from Qt import QtGui, QtWidgets, QtCore
class Window(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.resize(500, 400)
self.uiItems = QtWidgets.QTreeView()
self.uiItems.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.uiItems.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.uiItems.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.uiItems.setModel(QtGui.QStandardItemModel())
self.uiItems.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.uiItems)
self.setLayout(self.layout)
for i in range(3):
parent1 = QtGui.QStandardItem('Parente Item ' + str(i))
parent2 = QtGui.QStandardItem()
parent3 = QtGui.QStandardItem()
self.uiItems.model().appendRow([parent1, parent2, parent3])
for x in range(3):
col1 = QtGui.QStandardItem('Child Item' + str(x))
col2 = QtGui.QStandardItem('Item' + str(x))
col3 = QtGui.QStandardItem('Item' + str(x))
col3.setData(self.createDotPixmap(), role=QtCore.Qt.DecorationRole)
parent1.appendRow([col1,col2,col3])
self.uiItems.expandAll()
def createRectPixmap(self, col=QtGui.QColor(240,50,50)):
px = QtGui.QPixmap(12,12)
px.fill(QtCore.Qt.transparent)
pxSize = px.rect().adjusted(1,1,-1,-1)
painter = QtGui.QPainter(px)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(col)
painter.setPen(QtGui.QPen(QtGui.QColor(150,20,20), 1.25))
painter.drawRect(pxSize)
painter.end()
return px
def createDotPixmap(self, col=QtGui.QColor(128,128,128)):
px = QtGui.QPixmap(12,12)
px.fill(QtCore.Qt.transparent)
pxSize = px.rect().adjusted(1,1,-1,-1)
painter = QtGui.QPainter(px)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(col)
painter.setPen(QtGui.QPen(QtGui.QColor(15,15,15), 1.25))
painter.drawEllipse(pxSize)
painter.end()
return px
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Window()
ex.show()
app.exec_()
Solution
The solution is:
import os, sys, pprint
from Qt import QtGui, QtWidgets, QtCore
DecorationRole2 = QtCore.Qt.UserRole + 1000
class IconDelegate(QtWidgets.QStyledItemDelegate):
def paint(self, painter, option, index):
super(self.__class__, self).paint(painter, option, index)
value = index.data(DecorationRole2)
if value:
margin = 10
mode = QtGui.QIcon.Normal
if not (option.state & QtWidgets.QStyle.State_Enabled):
mode = QtGui.QIcon.Disabled
elif option.state & QtWidgets.QStyle.State_Selected:
mode = QtGui.QIcon.Selected
if isinstance(value, QtGui.QPixmap):
icon = QtGui.QIcon(value)
option.decorationSize = value.size() / value.devicePixelRatio()
elif isinstance(value, QtGui.QColor):
pixmap = QtGui.QPixmap(option.decorationSize)
pixmap.fill(value)
icon = QtGui.QIcon(pixmap)
elif isinstance(value, QtGui.Image):
icon = QtGui.QIcon(QtGui.QPixmap.fromImage(value))
option.decorationSize = value.size() / value.devicePixelRatio()
elif isinstance(value, QtGui.QIcon):
state = QtGui.QIcon.On if option.state & QtWidgets.QStyle.State_Open else QtGui.QIcon.Off
actualSize = option.icon.actualSize(option.decorationSize, mode, state)
option.decorationSize = QtCore.QSize(min(option.decorationSize.width(), actualSize.width()), min(option.decorationSize.height(), actualSize.height()))
r = QtCore.QRect(QtCore.QPoint(), option.decorationSize)
r.moveCenter(option.rect.center())
r.setRight(option.rect.right() - margin)
state = QtGui.QIcon.On if option.state & QtWidgets.QStyle.State_Open else QtGui.QIcon.Off
icon.paint(painter, r, QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter, mode, state)
class Window(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.resize(500, 400)
self.uiItems = QtWidgets.QTreeView()
self.uiItems.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.uiItems.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.uiItems.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.uiItems.setModel(QtGui.QStandardItemModel())
self.uiItems.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
delegate = IconDelegate(self.uiItems)
self.uiItems.setItemDelegateForColumn(2, delegate)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.uiItems)
self.setLayout(self.layout)
for i in range(3):
parent1 = QtGui.QStandardItem('Parente Item ' + str(i))
parent2 = QtGui.QStandardItem()
parent3 = QtGui.QStandardItem()
self.uiItems.model().appendRow([parent1, parent2, parent3])
for x in range(3):
col1 = QtGui.QStandardItem('Child Item' + str(x))
col2 = QtGui.QStandardItem('Item' + str(x))
col3 = QtGui.QStandardItem('Item' + str(x))
col3.setData(self.createDotPixmap(), role=QtCore.Qt.DecorationRole)
col3.setData(self.createRectPixmap(), role=DecorationRole2)
parent1.appendRow([col1,col2,col3])
self.uiItems.expandAll()
def createRectPixmap(self, col=QtGui.QColor(240,50,50)):
px = QtGui.QPixmap(12,12)
px.fill(QtCore.Qt.transparent)
pxSize = px.rect().adjusted(1,1,-1,-1)
painter = QtGui.QPainter(px)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(col)
painter.setPen(QtGui.QPen(QtGui.QColor(150,20,20), 1.25))
painter.drawRect(pxSize)
painter.end()
return px
def createDotPixmap(self, col=QtGui.QColor(128,128,128)):
px = QtGui.QPixmap(12,12)
px.fill(QtCore.Qt.transparent)
pxSize = px.rect().adjusted(1,1,-1,-1)
painter = QtGui.QPainter(px)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(col)
painter.setPen(QtGui.QPen(QtGui.QColor(15,15,15), 1.25))
painter.drawEllipse(pxSize)
painter.end()
return px
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Window()
ex.show()
app.exec_()
Answered By - eyllanesc
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.