def __getStyleOption(self, row, col): tab = self.__tabAt(row, col) if not tab: return None opt = QStyleOptionTab() opt.initFrom(self) opt.state &= ~(QStyle.State_HasFocus | QStyle.State_MouseOver) opt.rect = self.tabRect(row, col) isCurrent = (row, col) == self.__selectedIndex opt.row = 0 if (row, col) == self.__pressedIndex: opt.state |= QStyle.State_Sunken if isCurrent: opt.state |= QStyle.State_Selected if isCurrent and self.hasFocus(): opt.state |= QStyle.State_HasFocus if not tab.enabled: opt.state &= ~QStyle.State_Enabled if self.isActiveWindow(): opt.state |= QStyle.State_Active if opt.rect == self.__hoverRect: opt.state |= QStyle.State_MouseOver opt.shape = QTabBar.RoundedNorth opt.text = tab.text if tab.textColor.isValid(): opt.palette.setColor(self.foregroundRole(), tab.textColor) opt.icon = tab.icon opt.iconSize = self.iconSize() if row == self.__selectedIndex[0]: if col > 0 and col - 1 == self.__selectedIndex[1]: opt.selectedPosition = QStyleOptionTab.PreviousIsSelected elif col < self.numTabsInRow(row) - 1 and \ col + 1 == self.__selectedIndex[1]: opt.selectedPosition = QStyleOptionTab.NextIsSelected else: opt.selectedPosition = QStyleOptionTab.NotAdjacent else: opt.selectedPosition = QStyleOptionTab.NotAdjacent if col == 0: if self.numTabsInRow(row) > 1: opt.position = QStyleOptionTab.Beginning else: opt.position = QStyleOptionTab.OnlyOneTab elif col == self.numTabsInRow(row) - 1: opt.position = QStyleOptionTab.End else: opt.position = QStyleOptionTab.Middle return opt
def __layoutTabs(self): self.__layoutDirty = False numrows = len(self.__tabList) taboverlap = QStyleOptionTab() taboverlap.shape = QTabBar.RoundedNorth baseoverlap = self.baseOverlap() rowoverlap = self.style().pixelMetric(QStyle.PM_TabBarTabShiftVertical, taboverlap, self) rowoverlap += baseoverlap maxWidth = 0 maxHeight = 0 maxNumTabs = 0 maxRowWidth = 0 rowpcts = [] for i in range(numrows): maxNumTabs = max(self.numTabsInRow(i), maxNumTabs) mw = 0 rowpcts.append([]) for j in range(len(self.__tabList[i])): sz = self.tabSizeHint(i, j) mw += sz.width() maxWidth = max(sz.width(), maxWidth) maxHeight = max(maxHeight, sz.height()) rowpcts[i].append(sz.width()) rowpcts[i] = [float(x) / mw for x in rowpcts[i]] maxRowWidth = max(mw, maxRowWidth) maxHeight -= rowoverlap centerOffset = 0 for i in range(numrows): x = 0 if i == self.__selectedIndex[0]: y = (len(self.__tabList) - 1) * maxHeight elif i < self.__selectedIndex[0] or self.__selectedIndex[0] == -1: y = i * maxHeight else: y = (i - 1) * maxHeight for j in range(self.numTabsInRow(i)): w = rowpcts[i][j] * maxRowWidth if j == self.numTabsInRow(i) - 1 and \ (x + int(w)) < maxRowWidth: w = maxRowWidth - x self.__tabList[i][j].rect = QRect(x + centerOffset, y, int(w), maxHeight + rowoverlap) x += int(w) self.tabLayoutChange()
def dump(self): taboverlap = QStyleOptionTab() taboverlap.shape = QTabBar.RoundedNorth for var in ( 'PM_TabBarTabOverlap', 'PM_TabBarTabHSpace', 'PM_TabBarTabShiftHorizontal', 'PM_TabBarTabVSpace', 'PM_TabBarTabShiftVertical', 'PM_TabBarBaseHeight', 'PM_TabBarBaseOverlap', ): val = self.style().pixelMetric(getattr(QStyle, var), taboverlap, self) sys.stdout.write("%s = %s\n" % (var, val))
def paintEvent(self, e): tabOverlap = QStyleOptionTab() tabOverlap.shape = QTabBar.RoundedNorth optTabBase = QStyleOptionTabBarBase() optTabBase.initFrom(self) optTabBase.shape = QTabBar.RoundedNorth optTabBase.tabBarRect = QRect() painter = QPainter(self) selected = (0, 0) for i in range(len(self.__tabList)): for j in range(len(self.__tabList[i])): tab = self.__getStyleOption(i, j) if not (tab.state & QStyle.State_Enabled): tab.palette.setCurrentColorGroup(QPalette.Disabled) optTabBase.tabBarRect |= tab.rect if (i, j) == self.__selectedIndex: selected = (i, j) optTabBase.selectedTabRect = tab.rect continue self.style().drawControl(QStyle.CE_TabBarTab, tab, painter, self) if selected != (-1, -1): for j in range(len(self.__tabList[selected[0]])): tab = self.__getStyleOption(selected[0], j) self.style().drawControl(QStyle.CE_TabBarTab, tab, painter, self) tab = self.__getStyleOption(selected[0], selected[1]) painter.eraseRect(tab.rect) self.style().drawControl(QStyle.CE_TabBarTab, tab, painter, self)
def baseOverlap(self): taboverlap = QStyleOptionTab() taboverlap.shape = QTabBar.RoundedNorth return self.style().pixelMetric(QStyle.PM_TabBarBaseOverlap, taboverlap, self)