def paintEvent(self, event: QPaintEvent): _start = perf_counter() num = self.num_tabs selected = self.selected arrow_width = self._arrow_width height = self.height() width = self._button_width first_width = self._first_button_width button = self._button_path button_box = QRect(0, 0, width + arrow_width, height) first_box = QRect(0, 0, first_width + arrow_width, height) icon_area = QRect(arrow_width + 10, 0, max(48, width / 2), height) text_box = QRect(arrow_width, 0, width - arrow_width, height) text_flags = Qt.AlignCenter | Qt.AlignVCenter states = self.states painter = QPainter(self) region = event.region() painter.setClipRegion(region) #torender = self._tabs_within(event.region()) #print("regions:") #for rect in event.region().rects(): # print(" - ", rect) #painter.setPen(Qt.NoPen) painter.setPen( QPen(Qt.black, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) titleFont = painter.font() titleFont.setPointSizeF(14) titleFont.setBold(True) painter.setFont(titleFont) painter.translate(num * width + first_width, 0) if region.intersects(painter.transform().mapRect(button_box)): painter.setBrush(states[num].get_color(num == selected)) painter.drawPath(self._last_button_path) for i in reversed(range(num)): painter.translate(-width, 0) if not region.intersects(painter.transform().mapRect(button_box)): continue painter.setBrush(states[i].get_color(i == selected)) painter.drawPath(button) if states[i].state == State.ACTIVE: painter.save() painter.setPen(Qt.NoPen) gw = (width + self._arrow_width) * 2 gradient = QLinearGradient(0, 0, gw, 0) value = self._working_anim.value gradient.setColorAt(max(0.0, value - 0.2), QColor(255, 255, 255, 0)) gradient.setColorAt(value, QColor(255, 255, 255, 180)) gradient.setColorAt(min(1.0, value + 0.2), QColor(255, 255, 255, 0)) brush = QBrush(gradient) brush.setTransform(brush.transform().translate(-gw / 4, 0)) gradient_height = int(height * 0.2) painter.setBrush(brush) #painter.setClipRect(0, 0, width+self._arrow_width, gradient_height) #painter.drawPath(button) #painter.setClipRect(0, height-gradient_height, width+self._arrow_width, gradient_height) painter.drawPath(button) self._active_box = painter.transform().mapRect(button_box) painter.restore() #if states[i].icon: # states[i].icon.paint(painter, icon_area) text = states[i].text if text: _, _, short = text.rpartition('-') painter.drawText(text_box, text_flags, short.capitalize()) if region.intersects(first_box): painter.resetTransform() painter.setBrush(State.UNKNOWN.get_color(-1 == selected)) painter.drawPath(self._first_button_path) if self.is_running: icon = self.style().standardIcon(QStyle.SP_MediaStop) else: icon = self.style().standardIcon(QStyle.SP_MediaPlay) size = min(self._first_button_width, self.height()) * 0.8 painter.translate(5, (self.height() - size) / 2) icon.paint(painter, QRect(0, 0, size, size)) _end = perf_counter() if not self._paint_times: self._paint_times = times = [] else: times = self._paint_times times.append(_end - _start) if len(times) > 60: avg = sum(times) / len(times) * 1000000 print("Average render time %.2fns" % (avg, )) self._paint_times = None