def sectionSizeFromContents(self, logicalIndex): """ :parameters: :return: :rtype: """ size = QtGui.QHeaderView.sectionSizeFromContents(self, logicalIndex) if self.model(): if self.isSortIndicatorShown() and not self.model().headerData( logicalIndex, self.orientation(), common.ROLE_IS_SORTABLE): # remove the sort indicator margin for columns that aren't sortable opt = QtGui.QStyleOptionHeader() self.initStyleOption(opt) margin = self.style().pixelMetric(QtGui.QStyle.PM_HeaderMargin, opt, self) if self.orientation() == QtCore.Qt.Horizontal: size.setWidth(size.width() - size.height() - margin) else: size.setHeight(size.height() - size.width() - margin) # compensate for icon if self.model().headerData(logicalIndex, QtCore.Qt.Horizontal, role=QtCore.Qt.DecorationRole): size.setWidth(size.width() + 12) return size
def paintSection(self, painter, rect, logicalIndex): """ Re-implementation of QHeaderView.paintSection() to deal with multi-sorting. """ if not rect.isValid(): return painter.save() # get the state of the section opt = QtGui.QStyleOptionHeader() self.initStyleOption(opt) state = QtGui.QStyle.State_None if self.isEnabled(): state |= QtGui.QStyle.State_Enabled if self.window().isActiveWindow(): state |= QtGui.QStyle.State_Active # store some frequently used objects setOptBrush = opt.palette.setBrush getHeaderData = self.model().headerData palette = self.palette() orientation = self.orientation() # set up sorted column headers sortColumns = self.model().sorter.sortColumns sortDirections = self.model().sorter.sortDirections sortIndex = -1 if self.isSortIndicatorShown(): try: sortIndex = sortColumns.index(logicalIndex) except ValueError: pass # this column is not a part of the multi-sort if sortIndex >= 0: opt.sortIndicator = QtGui.QStyleOptionHeader.SortDown if sortDirections[ sortIndex] == QtCore.Qt.AscendingOrder else QtGui.QStyleOptionHeader.SortUp # paint sorted column slightly darker than normal setOptBrush(QtGui.QPalette.Button, QtGui.QBrush(palette.button().color().darker(110))) setOptBrush(QtGui.QPalette.Window, QtGui.QBrush(palette.window().color().darker(110))) setOptBrush(QtGui.QPalette.Dark, QtGui.QBrush(palette.dark().color().darker(110))) # setup the style options structure opt.rect = rect opt.section = logicalIndex opt.state |= state opt.text = getHeaderData(logicalIndex, orientation, QtCore.Qt.DisplayRole) textAlignment = getHeaderData(logicalIndex, orientation, QtCore.Qt.TextAlignmentRole) opt.textAlignment = QtCore.Qt.Alignment( textAlignment if textAlignment is not None else self. defaultAlignment()) opt.iconAlignment = QtCore.Qt.AlignVCenter if self.textElideMode() != QtCore.Qt.ElideNone: opt.text = opt.fontMetrics.elidedText(opt.text, self.textElideMode(), rect.width() - 4) icon = getHeaderData(logicalIndex, orientation, QtCore.Qt.DecorationRole) if icon: opt.icon = icon foregroundBrush = getHeaderData(logicalIndex, orientation, QtCore.Qt.ForegroundRole) if foregroundBrush: setOptBrush(QtGui.QPalette.ButtonText, foregroundBrush) backgroundBrush = getHeaderData(logicalIndex, orientation, QtCore.Qt.BackgroundRole) if backgroundBrush: setOptBrush(QtGui.QPalette.Button, backgroundBrush) setOptBrush(QtGui.QPalette.Window, backgroundBrush) painter.setBrushOrigin(opt.rect.topLeft()) # determine column position visual = self.visualIndex(logicalIndex) assert visual != -1 if self.count() == 1: opt.position = QtGui.QStyleOptionHeader.OnlyOneSection elif visual == 0: opt.position = QtGui.QStyleOptionHeader.Beginning elif visual == self.count() - 1: opt.position = QtGui.QStyleOptionHeader.End else: opt.position = QtGui.QStyleOptionHeader.Middle opt.orientation = orientation # draw the section self.style().drawControl(QtGui.QStyle.CE_Header, opt, painter, self) painter.restore() # darken if it is a locked column in the view if not self.__columnIsUnlocked(logicalIndex): painter.fillRect(rect, QtGui.QColor(0, 0, 0, 40)) # paint a number overlay when multi-sorting if sortIndex >= 0 and len(sortColumns) > 1: # paint a number indicator when multi-sorting text = str(sortIndex + 1) headerFont = QtGui.QFont(painter.font()) headerFont.setPointSize(headerFont.pointSize() - 2) textWidth = QtGui.QFontMetrics(headerFont).boundingRect( text).width() # calculate the indicator location point = QtCore.QPointF(rect.bottomRight()) point.setX(point.x() - textWidth - 1) point.setY(point.y() - 1) # paint the number overlay painter.save() painter.setCompositionMode(QtGui.QPainter.CompositionMode_Source) painter.setFont(headerFont) painter.drawText(point, text) painter.restore()