<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr" class="gmail_attr">Il giorno gio 25 apr 2019 alle ore 21:04 Maziar Parsijani <<a href="mailto:maziar.parsijani@gmail.com">maziar.parsijani@gmail.com</a>> ha scritto:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Hi</div><div>I want to know if it is possible to change font for each column in Qtableview and if it is possible even more different appearances in columns like backgrounds and font colors.</div></div></blockquote><div><br></div><div><br></div></div><div dir="ltr">There are different possible approaches, and the choice usually depends on how the table data is filled and if it's editable.<div>The most common way is to set the QtCore.Qt.ItemDataRole for each field index, by providing the FontRole, ForegroundRole and BackgroundRole to the index.setData(value, role).<br>If you're using a QStandardItemModel, the data is simple and you don't need interaction, just use setData method on each item.</div><div><br></div><div>If you are using any model based on QAbstractItemModel you could subclass its data method like this:</div><div><br></div><div><div><font face="monospace, monospace">class SimpleModel(QtGui.QStandardItemModel):</font></div><div><span style="font-family:monospace,monospace">    backgrounds = QtGui.QColor(QtCore.Qt.lightGray), QtGui.QColor(QtCore.Qt.darkCyan), QtGui.QColor(QtCore.Qt.darkGray)</span><br></div><div><font face="monospace, monospace">    foregrounds = QtGui.QColor(QtCore.Qt.darkGreen), QtGui.QColor(QtCore.Qt.darkBlue), QtGui.QColor(QtCore.Qt.yellow)</font></div><div><div><font face="monospace, monospace">    fonts = QtGui.QFont('monospace'), QtGui.QFont(), QtGui.QFont('times')</font></div></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    def data(self, index, role=QtCore.Qt.DisplayRole):</font></div><div><font face="monospace, monospace">        if role == QtCore.Qt.BackgroundRole:</font></div><div><font face="monospace, monospace">            return self.backgrounds[index.column()]</font></div><div><span style="font-family:monospace,monospace">        elif role == QtCore.Qt.ForegroundRole:</span><br></div><div><font face="monospace, monospace">            return self.foregrounds[index.column()]</font></div><div><font face="monospace, monospace">        elif role == QtCore.Qt.FontRole:</font></div><div><font face="monospace, monospace">            return self.fonts[index.column()]</font></div><div><span style="font-family:monospace,monospace">        return QtGui.QStandardItemModel.data(self, index, role)</span><br></div></div><div><br></div><div>Note that you could also set a QIdentityProxyModel with your original model (and use the proxy on the table instead) and then implement the data() method in the same way. Just use the code above with QIdentityProxyModel instead of QStandardItemModel, do a setSource(originalModel) and you're done; this is usually better and much more transparent.</div><div><br></div><div>If you cannot have that kind of access, the alternative is to create your own item delegate subclass and implement the paint() method. Be aware that item painting is not an easy task, expecially if you want to mimic the default implementation.</div><div><br></div><div><div><font face="monospace, monospace">class SimpleDelegate(QtWidgets.QStyledItemDelegate):</font></div><div><font face="monospace, monospace">    backgrounds = QtGui.QColor(QtCore.Qt.lightGray), QtGui.QColor(QtCore.Qt.darkCyan), QtGui.QColor(QtCore.Qt.darkGray)</font></div><div><font face="monospace, monospace">    foregrounds = QtGui.QColor(QtCore.Qt.darkGreen), QtGui.QColor(QtCore.Qt.darkBlue), QtGui.QColor(QtCore.Qt.yellow)</font></div><div><font face="monospace, monospace">    fonts = QtGui.QFont('monospace'), QtGui.QFont(), QtGui.QFont('times')</font></div><div><font face="monospace, monospace">    fontData = zip(backgrounds, foregrounds, fonts)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    def paint(self, qp, option, index):</font></div><div><font face="monospace, monospace">        #painting needs performance, let's get all data at once</font></div><div><font face="monospace, monospace">        background, foreground, font = self.fontData[index.column()]</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">        # never reuse the given option argument, always create a new one based on it!</font></div><div><font face="monospace, monospace">        # reusing QStyleOptions might create issues and inconsistencies with item "siblings"</font></div><div><font face="monospace, monospace">        option = QtWidgets.QStyleOptionViewItem(option)</font></div><div><font face="monospace, monospace">        self.initStyleOption(option, index)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">        # reset the text so that QStyle won't paint it</font></div><div><font face="monospace, monospace">        option.text = ''</font></div><div><font face="monospace, monospace">        option.backgroundBrush = background</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">        widget = option.widget</font></div><div><span style="font-family:monospace,monospace">        style = widget.style()</span><br></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">        # we could use the drawPrimitive instead, but it won't paint the decoration (icon), </font></div><div><font face="monospace, monospace">        # if it exists; drawControl paints everything, that's why I cleared the text before,</font></div><div><font face="monospace, monospace">        # otherwise you'll see the text drawn twice</font></div><div><font face="monospace, monospace">        style.drawControl(QtWidgets.QStyle.CE_ItemViewItem, option, qp)</font></div><div><font face="monospace, monospace">        #style.drawPrimitive(QtWidgets.QStyle.PE_PanelItemViewItem, option, qp)</font></div><div><br></div><div><span style="font-family:monospace,monospace">        # get the rectangle available for item text and adjust it to standard margins;</span></div><div><span style="font-family:monospace,monospace">        # one pixel is added for consistency with the original Qt painting behavior</span></div><div><span style="font-family:monospace,monospace">        textRect = style.subElementRect(style.SE_ItemViewItemText, option, widget)</span><br></div><div><font face="monospace, monospace">        margin = style.pixelMetric(style.PM_FocusFrameHMargin, option, widget) + 1</font></div><div><font face="monospace, monospace">        textRect.adjust(margin, 0, -margin, 0)</font></div><div><font face="monospace, monospace"><br></font></div><div><div><font face="monospace, monospace">        # set the foreground color to the palette (not to the painter!)</font></div><div><span style="font-family:monospace,monospace">        option.palette.setColor(option.palette.Active, option.palette.Base, foreground)</span><br></div><div><span style="font-family:monospace,monospace">        # if you want to have differrent colors for disabled items, use again the setColor</span><br></div><div><font face="monospace, monospace">        #</font><span style="font-family:monospace,monospace"> </span><span style="font-family:monospace,monospace">method</span><span style="font-family:monospace,monospace"> with option.palette.Disabled</span></div><div><span style="font-family:monospace,monospace">        #option.palette.setColor(option.palette.Disabled, option.palette.Base, disabledColor)</span><br></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">        qp.setFont(font)</font></div><div><font face="monospace, monospace">        style.drawItemText(qp, textRect, style.visualAlignment(option.direction, option.displayAlignment), </font></div><div><font face="monospace, monospace">            option.palette, option.state & style.State_Enabled, </font></div><div><span style="font-family:monospace,monospace">            option.fontMetrics.elidedText(index.data(), option.textElideMode, textRect.width()), </span><br></div><div><font face="monospace, monospace">            option.palette.Base)</font></div></div></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">class MyTable(QtWidget.QTableView):</font></div><div><font face="monospace, monospace">    def __init__(self, *args, **kwargs):</font></div><div><font face="monospace, monospace">        QtWidgets.QTableView.</font><span style="font-family:monospace,monospace">__init__(self, *args, **kwargs)</span></div><div><span style="font-family:monospace,monospace">        self.setItemDelegate(SimpleDelegate())</span></div><div><font face="monospace, monospace"><br></font></div><div><br></div><div>Unfortunately, this is not quite perfect: while it should be fine for most user cases, it doesn't take into account the word wrapping, meaning that the text will always be on one line, no matter how much the row height is big. To fix this, it would take about 60-70 more lines of code, which would be run at each paintEvent for each visible item. Not always a good idea, but if you think it's good enough, you can find how it's done from the calculateElidedText method called by viewItemDrawText in here: <a href="https://code.woboq.org/qt5/qtbase/src/widgets/styles/qcommonstyle.cpp.html">https://code.woboq.org/qt5/qtbase/src/widgets/styles/qcommonstyle.cpp.html</a></div><div><br></div><div>Cheers,</div><div>Maurizio</div><div><br></div></div></div></div></div></div></div>-- <br><div dir="ltr" class="gmail_signature">È difficile avere una convinzione precisa quando si parla delle ragioni del cuore. - "Sostiene Pereira", Antonio Tabucchi<br><a href="http://www.jidesk.net" target="_blank">http://www.jidesk.net</a></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>