def paint(self, painter, option, widget=None): rect = self.rect() if self.isSelected(): option.state ^= QStyle.State_Selected font = self.document().defaultFont() painter.setFont(font) if self.parent: draw_text = self.node_inst.description if self.parent.x() > self.x(): # node is to the left fm = QFontMetrics(font) x = rect.width() / 2 - fm.width(draw_text) - 4 else: x = rect.width() / 2 + 4 painter.drawText(QPointF(x, -self.line_descent - 1), draw_text) painter.save() painter.setBrush(self.backgroundBrush) painter.setPen(QPen(Qt.black, 3 if self.isSelected() else 0)) adjrect = rect.adjusted(-3, 0, 0, 0) if not self.node_inst.children: painter.drawRoundedRect(adjrect, 4, 4) else: painter.drawRect(adjrect) painter.restore() painter.setClipRect(rect) return QGraphicsTextItem.paint(self, painter, option, widget)
def _update_points_labels(self): if self.plotdata.points is None: return for point_label in self.plotdata.point_labels: self.graph.plot_widget.removeItem(point_label) self.plotdata.point_labels = [] sx, sy = self.graph.view_box.viewPixelSize() for row in self.plotdata.points: ti = TextItem() metrics = QFontMetrics(ti.textItem.font()) text_width = ((RANGE.width()) / 2. - np.abs(row[0])) / sx name = row[2].name ti.setText(name) ti.setTextWidth(text_width) ti.setColor(QColor(0, 0, 0)) br = ti.boundingRect() width = metrics.width( name) if metrics.width(name) < br.width() else br.width() width = sx * (width + 5) height = sy * br.height() ti.setPos(row[0] - (row[0] < 0) * width, row[1] + (row[1] > 0) * height) self.plotdata.point_labels.append(ti) self.graph.plot_widget.addItem(ti)
def paint(self, painter, option, widget=None): rect = self.rect() if self.isSelected(): option.state ^= QStyle.State_Selected font = self.document().defaultFont() painter.setFont(font) if self.parent: draw_text = str(self.tree_adapter.short_rule(self.node_inst)) if self.parent.x() > self.x(): # node is to the left fm = QFontMetrics(font) x = rect.width() / 2 - fm.width(draw_text) - 4 else: x = rect.width() / 2 + 4 painter.drawText(QPointF(x, -self.line_descent - 1), draw_text) painter.save() painter.setBrush(self.backgroundBrush) painter.setPen(QPen(Qt.black, 3 if self.isSelected() else 0)) adjrect = rect.adjusted(-3, 0, 0, 0) if not self.tree_adapter.has_children(self.node_inst): painter.drawRoundedRect(adjrect, 4, 4) else: painter.drawRect(adjrect) painter.restore() painter.setClipRect(rect) return QGraphicsTextItem.paint(self, painter, option, widget)
def recompute_binnings(self): if self.is_valid and self.var.is_continuous: # binning is computed on valid var data, ignoring any cvar nans column = self.data.get_column_view(self.var)[0].astype(float) if np.any(np.isfinite(column)): if self.var.is_time: self.binnings = time_binnings(column, min_unique=5) else: self.binnings = decimal_binnings( column, min_width=self.min_var_resolution(self.var), add_unique=10, min_unique=5, ) fm = QFontMetrics(self.font()) width = max( fm.size(Qt.TextSingleLine, self._short_text(binning.width_label)).width() for binning in self.binnings) self.bin_width_label.setFixedWidth(width) max_bins = len(self.binnings) - 1 else: self.binnings = [] max_bins = 0 self.controls.number_of_bins.setMaximum(max_bins) self.number_of_bins = min( max_bins, self._user_var_bins.get(self.var, self.number_of_bins)) self._set_bin_width_slider_label()
def splash_screen(): """ """ pm = QPixmap( pkg_resources.resource_filename( __name__, "icons/orange-splash-screen.png") ) version = QCoreApplication.applicationVersion() size = 21 if len(version) < 5 else 16 font = QFont("Helvetica") font.setPixelSize(size) font.setBold(True) font.setItalic(True) font.setLetterSpacing(QFont.AbsoluteSpacing, 2) metrics = QFontMetrics(font) br = metrics.boundingRect(version).adjusted(-5, 0, 5, 0) br.moveCenter(QPoint(436, 224)) p = QPainter(pm) p.setRenderHint(QPainter.Antialiasing) p.setRenderHint(QPainter.TextAntialiasing) p.setFont(font) p.setPen(QColor("#231F20")) p.drawText(br, Qt.AlignCenter, version) p.end() return pm, QRect(88, 193, 200, 20)
def splash_screen(): path = pkg_resources.resource_filename( __name__, "icons/orange-splash-screen.png") pm = QPixmap(path) version = Config.ApplicationVersion if version: version_parsed = LooseVersion(version) version_comp = version_parsed.version version = ".".join(map(str, version_comp[:2])) size = 21 if len(version) < 5 else 16 font = QFont("Helvetica") font.setPixelSize(size) font.setBold(True) font.setItalic(True) font.setLetterSpacing(QFont.AbsoluteSpacing, 2) metrics = QFontMetrics(font) br = metrics.boundingRect(version).adjusted(-5, 0, 5, 0) br.moveCenter(QPoint(436, 224)) p = QPainter(pm) p.setRenderHint(QPainter.Antialiasing) p.setRenderHint(QPainter.TextAntialiasing) p.setFont(font) p.setPen(QColor("#231F20")) p.drawText(br, Qt.AlignCenter, version) p.end() return pm, QRect(88, 193, 200, 20)
def __naturalsh(self): fm = QFontMetrics(self.font()) spacing = self.__spacing N = len(self.__items) width = max((fm.width(text) for text in self.__items), default=0) height = N * fm.height() + (N - 1) * spacing return QSizeF(width, height)
def __naturalsh(self) -> QSizeF: """Return the natural size hint (preferred sh with no constraints).""" fm = QFontMetrics(self.font()) spacing = self.__spacing N = len(self.__items) width = self.__width_for_font(self.font()) height = N * fm.height() + max(N - 1, 0) * spacing return QSizeF(width, height)
def __width_for_font(self, font: QFont) -> float: """Return item width for the font""" key = font.key() if key in self.__widthCache: return self.__widthCache[key] fm = QFontMetrics(font) width = max((fm.width(text) for text in self.__items), default=0) self.__widthCache[key] = width return width
def __textLayout(self): fm = QFontMetrics(self.font()) text = self.defaultAction().text() words = deque(text.split()) lines = [] curr_line = "" curr_line_word_count = 0 option = QStyleOptionToolButton() option.initFrom(self) margin = self.style().pixelMetric(QStyle.PM_ButtonMargin, option, self) width = self.width() - 2 * margin while words: w = words.popleft() if curr_line_word_count: line_extended = " ".join([curr_line, w]) else: line_extended = w line_w = fm.boundingRect(line_extended).width() if line_w >= width: if curr_line_word_count == 0 or len(lines) == 1: # A single word that is too long must be elided. # Also if the text overflows 2 lines # Warning: hardcoded max lines curr_line = fm.elidedText(line_extended, Qt.ElideRight, width) curr_line = curr_line else: # Put the word back words.appendleft(w) lines.append(curr_line) curr_line = "" curr_line_word_count = 0 if len(lines) == 2: break else: curr_line = line_extended curr_line_word_count += 1 if curr_line: lines.append(curr_line) text = "\n".join(lines) text = text.replace('&', '&&') # Need escaped ampersand to show self.__text = text
def __textLayout(self): fm = QFontMetrics(self.font()) text = six.text_type(self.defaultAction().text()) words = deque(text.split()) lines = [] curr_line = "" curr_line_word_count = 0 option = QStyleOptionToolButton() option.initFrom(self) margin = self.style().pixelMetric(QStyle.PM_ButtonMargin, option, self) width = self.width() - 2 * margin while words: w = words.popleft() if curr_line_word_count: line_extended = " ".join([curr_line, w]) else: line_extended = w line_w = fm.boundingRect(line_extended).width() if line_w >= width: if curr_line_word_count == 0 or len(lines) == 1: # A single word that is too long must be elided. # Also if the text overflows 2 lines # Warning: hardcoded max lines curr_line = fm.elidedText(line_extended, Qt.ElideRight, width) curr_line = six.text_type(curr_line) else: # Put the word back words.appendleft(w) lines.append(curr_line) curr_line = "" curr_line_word_count = 0 if len(lines) == 2: break else: curr_line = line_extended curr_line_word_count += 1 if curr_line: lines.append(curr_line) text = "\n".join(lines) text = text.replace('&', '&&') # Need escaped ampersand to show self.__text = text
def update_contents(self): self.prepareGeometryChange() self.setTextWidth(-1) self.setTextWidth(self.document().idealWidth()) self.droplet.setPos(self.rect().center().x(), self.rect().height()) self.droplet.setVisible(bool(self.branches)) fm = QFontMetrics(self.document().defaultFont()) attr = self.node_inst.attr self.attr_text_w = fm.width(attr.name if attr else "") self.attr_text_h = fm.lineSpacing() self.line_descent = fm.descent() if self.pie is not None: self.pie.setPos(self.rect().right(), self.rect().center().y())
def update_contents(self): self.prepareGeometryChange() self.setTextWidth(-1) self.setTextWidth(self.document().idealWidth()) self.droplet.setPos(self.rect().center().x(), self.rect().height()) self.droplet.setVisible(bool(self.branches)) fm = QFontMetrics(self.document().defaultFont()) attr = self.tree_adapter.attribute(self.node_inst) self.attr_text_w = fm.width(attr.name if attr else "") self.attr_text_h = fm.lineSpacing() self.line_descent = fm.descent() if self.pie is not None: self.pie.setPos(self.rect().right(), self.rect().center().y())
def defaultTextGeometry(self, point): """ Return the default text geometry. Used in case the user single clicked in the scene. """ font = self.annotation_item.font() metrics = QFontMetrics(font) spacing = metrics.lineSpacing() margin = self.annotation_item.document().documentMargin() rect = QRectF(QPointF(point.x(), point.y() - spacing - margin), QSizeF(150, spacing + 2 * margin)) return rect
def paintEvent(self, event): QLineEdit.paintEvent(self, event) if not self.text() and self.placeholderText( ) and not self.hasFocus(): p = QStylePainter(self) font = self.font() metrics = QFontMetrics(font) p.setFont(font) color = self.palette().color(QPalette.Mid) p.setPen(color) left, top, right, bottom = self.getTextMargins() contents = self.contentsRect() contents = contents.adjusted(left, top, -right, -bottom) text = metrics.elidedText(self.placeholderText(), Qt.ElideMiddle, contents.width()) p.drawText(contents, Qt.AlignLeft | Qt.AlignVCenter, text)
def __init__(self): self.data = None # GUI method_box = gui.vBox(self.controlArea, "Method") self.manifold_methods_combo = gui.comboBox( method_box, self, "manifold_method_index", items=[m.name for m in self.MANIFOLD_METHODS], callback=self.manifold_method_changed) self.params_box = gui.vBox(method_box) self.tsne_editor = TSNEParametersEditor(self) self.mds_editor = MDSParametersEditor(self) self.isomap_editor = IsomapParametersEditor(self) self.lle_editor = LocallyLinearEmbeddingParametersEditor(self) self.spectral_editor = SpectralEmbeddingParametersEditor(self) self.parameter_editors = [ self.tsne_editor, self.mds_editor, self.isomap_editor, self.lle_editor, self.spectral_editor] for editor in self.parameter_editors: self.params_box.layout().addWidget(editor) editor.hide() self.params_widget = self.parameter_editors[self.manifold_method_index] self.params_widget.show() output_box = gui.vBox(self.controlArea, "Output") self.n_components_spin = gui.spin( output_box, self, "n_components", 1, 10, label="Components:", controlWidth=QFontMetrics(self.font()).horizontalAdvance("0" * 10), alignment=Qt.AlignRight, callbackOnReturn=True, callback=self.settings_changed) gui.rubber(self.n_components_spin.box) self.apply_button = gui.auto_apply(self.buttonsArea, self)
def __init__(self, model, node_inst, parent=None): super().__init__(parent) self.model = model self.node_inst = node_inst fm = QFontMetrics(self.document().defaultFont()) attr = node_inst.attr self.attr_text_w = fm.width(attr.name if attr else "") self.attr_text_h = fm.lineSpacing() self.line_descent = fm.descent() self._rect = None if model.domain.class_var.is_discrete: self.pie = PieChart(node_inst.value, 8, self) else: self.pie = None
def show_tool_tip(pos: QPoint, text: str, widget: Optional[QWidget] = None, rect=QRect(), elide=Qt.ElideRight): """ Show a plain text tool tip with limited length, eliding if necessary. """ if widget is not None: screen = widget.screen() else: screen = QApplication.screenAt(pos) font = QApplication.font("QTipLabel") fm = QFontMetrics(font) geom = screen.availableSize() etext = fm.elidedText(text, elide, geom.width()) if etext != text: text = f"<span>{etext}</span>" QToolTip.showText(pos, text, widget, rect)
def setRowNames(self, names): if names is not None: names = np.asarray(names, dtype=object) layout = self.layout() font = self.font() font.setPixelSize(self.__barHeight) for i, grp in enumerate(self.__groups): grp.rownames = names[grp.indices] if names is not None else None item = layout.itemAt(i + 1, 3) if grp.rownames is not None: metrics = QFontMetrics(self.font()) rownames = [metrics.elidedText(rowname, Qt.ElideRight, ROW_NAMES_WIDTH) for rowname in grp.rownames] item.setItems(rownames) item.setVisible(self.__rowNamesVisible) else: item.setItems([]) item.setVisible(False) barplot = list(self.__plotItems())[i] baritems = barplot.items() if grp.rownames is None: tooltips = itertools.repeat("") else: tooltips = grp.rownames for baritem, tooltip in zip(baritems, tooltips): baritem.setToolTip(tooltip) self.layout().activate()
def paintEvent(self, event): super().paintEvent(event) p = QPainter(self) p.setRenderHint(QPainter.Antialiasing) p.setBrush(self.indicator_color) p.save() p.setPen(Qt.NoPen) fm = QFontMetrics(self.font()) width = self.rect().width() height = fm.height() + 6 rect = QRectF(0, 0, width, height) p.drawRoundedRect(rect, 5, 5) p.restore() textstart = (width - fm.width(self.indicator_text)) / 2 p.drawText(textstart, height / 2 + 5, self.indicator_text)
def __init__(self, tree_adapter, node_inst, parent=None): super().__init__(parent) self.tree_adapter = tree_adapter self.model = self.tree_adapter.model self.node_inst = node_inst fm = QFontMetrics(self.document().defaultFont()) attr = self.tree_adapter.attribute(node_inst) self.attr_text_w = fm.width(attr.name if attr else "") self.attr_text_h = fm.lineSpacing() self.line_descent = fm.descent() self._rect = None if self.model.domain.class_var.is_discrete: self.pie = PieChart(self.tree_adapter.get_distribution(node_inst)[0], 8, self) else: self.pie = None
def __layout(self): crect = self.contentsRect() spacing = self.__spacing N = len(self.__items) if not N: return fm = QFontMetrics(self.font()) naturalheight = fm.height() th = (crect.height() - (N - 1) * spacing) / N if th > naturalheight and N > 1: th = naturalheight spacing = (crect.height() - N * th) / (N - 1) for i, item in enumerate(self.__textitems): item.setPos(crect.left(), crect.top() + i * (th + spacing))
def generateDrawSpecs(self, p): axis_spec, tick_specs, text_specs = super().generateDrawSpecs(p) bounds = self.mapRectFromParent(self.geometry()) max_width = int(0.9 * bounds.width() / (len(text_specs) or 1)) elide = QFontMetrics(QWidget().font()).elidedText text_specs = [(rect, flags, elide(text, Qt.ElideRight, max_width)) for rect, flags, text in text_specs] return axis_spec, tick_specs, text_specs
def set_widget_value(widget, value): if isinstance(widget, QLineEdit): widget.setText(value) elif isinstance(widget, QPlainTextEdit): return widget.setPlainText(value) elif isinstance(widget, QLabel): if widget.openExternalLinks(): widget.setToolTip(value) metrics = QFontMetrics(widget.font()) display = metrics.elidedText(value, Qt.ElideRight, widget.width()) value = urllib.parse.unquote(value) # Because setText() escapes percent-encoded values and corrupts them value = '<a href="{value}">{display}</a>'.format(**locals()) widget.setText(value) elif isinstance(widget, QCheckBox): return widget.setChecked(value not in (False, '0', '', 'False')) else: raise RuntimeError()
def paintEvent(self, event): QLineEdit.paintEvent(self, event) if not self.text() and self.placeholderText() and \ not self.hasFocus(): p = QStylePainter(self) font = self.font() metrics = QFontMetrics(font) p.setFont(font) color = self.palette().color(QPalette.Mid) p.setPen(color) left, top, right, bottom = self.getTextMargins() contents = self.contentsRect() contents = contents.adjusted(left, top, -right, -bottom) text = metrics.elidedText(self.placeholderText(), Qt.ElideMiddle, contents.width()) p.drawText(contents, Qt.AlignLeft | Qt.AlignVCenter, text)
def _point_size(self, height): font = self.font() font.setPointSize(height) fix = 0 while QFontMetrics(font).lineSpacing() > height and height - fix > 1: fix += 1 font.setPointSize(height - fix) return height - fix
def splash_screen(): # type: () -> Tuple[QPixmap, QRect] """ Return a splash screen pixmap and an text area within it. The text area is used for displaying text messages during application startup. The default implementation returns a bland rectangle splash screen. Returns ------- t : Tuple[QPixmap, QRect] A QPixmap and a rect area within it. """ path = pkg_resources.resource_filename( __name__, "icons/orange-canvas-core-splash.svg") pm = QPixmap(path) version = QCoreApplication.applicationVersion() if version: version_parsed = LooseVersion(version) version_comp = version_parsed.version version = ".".join(map(str, version_comp[:2])) size = 21 if len(version) < 5 else 16 font = QFont() font.setPixelSize(size) font.setBold(True) font.setItalic(True) font.setLetterSpacing(QFont.AbsoluteSpacing, 2) metrics = QFontMetrics(font) br = metrics.boundingRect(version).adjusted(-5, 0, 5, 0) br.moveBottomRight(QPoint(pm.width() - 15, pm.height() - 15)) p = QPainter(pm) p.setRenderHint(QPainter.Antialiasing) p.setRenderHint(QPainter.TextAntialiasing) p.setFont(font) p.setPen(QColor("#231F20")) p.drawText(br, Qt.AlignCenter, version) p.end() textarea = QRect(15, 15, 170, 20) return pm, textarea
def _create_spin_parameter(self, name, minv, maxv, label): self.__spin_parameter_update(name) width = QFontMetrics(self.font()).horizontalAdvance("0" * 10) control = gui.spin( self, self, name, minv, maxv, alignment=Qt.AlignRight, callbackOnReturn=True, addToLayout=False, controlWidth=width, callback=lambda f=self.__spin_parameter_update, p=name: self.__parameter_changed(f, p)) self.layout().addRow(label, control)
def __init__(self, parent, highlighting_scheme, font): super().__init__(parent) self.highlighting_scheme = highlighting_scheme self.setFont(font) self.bold_font = QFont(font) self.bold_font.setBold(True) self.indentation_level = 0 self._char_4_width = QFontMetrics(font).horizontalAdvance('4444')
def sizeHint(self, which: Qt.SizeHint, constraint=QSizeF()) -> QSizeF: # reimplemented fm = QFontMetrics(self.font()) spacing = fm.lineSpacing() mleft, mtop, mright, mbottom = self.getContentsMargins() if self._root and which == Qt.PreferredSize: nleaves = len( [node for node in self._items.keys() if not node.branches]) base = max(10, min(spacing * 16, 250)) if self.orientation in [self.Left, self.Right]: return QSizeF(base, spacing * nleaves + mleft + mright) else: return QSizeF(spacing * nleaves + mtop + mbottom, base) elif which == Qt.MinimumSize: return QSizeF(mleft + mright + 10, mtop + mbottom + 10) else: return QSizeF()
def effective_point_size_for_height( font: QFont, height: float, step=0.25, minsize=1. ) -> float: font = QFont(font) start = max(math.ceil(height), minsize) font.setPointSizeF(start) fix = 0 while QFontMetrics(font).height() > height and start - (fix + step) > minsize: fix += step font.setPointSizeF(start - fix) return QFontInfo(font).pointSizeF()
def __elide(self): fm = QFontMetrics(self.__name_item.font()) text = fm.elidedText(self.__name, Qt.ElideRight, self.__max_len) self.__name_item.setText(text) if self.__value is not None: fm = QFontMetrics(self.__value_item.font()) text = fm.elidedText(self.__value, Qt.ElideRight, self.__max_len) self.__value_item.setText(text)
def _update_points_labels(self): if self.plotdata.points is None: return for point_label in self.plotdata.point_labels: self.graph.plot_widget.removeItem(point_label) self.plotdata.point_labels = [] sx, sy = self.graph.view_box.viewPixelSize() for row in self.plotdata.points: ti = TextItem() metrics = QFontMetrics(ti.textItem.font()) text_width = ((RANGE.width())/2. - np.abs(row[0])) / sx name = row[2].name ti.setText(name) ti.setTextWidth(text_width) ti.setColor(QColor(0, 0, 0)) br = ti.boundingRect() width = metrics.width(name) if metrics.width(name) < br.width() else br.width() width = sx * (width + 5) height = sy * br.height() ti.setPos(row[0] - (row[0] < 0) * width, row[1] + (row[1] > 0) * height) self.plotdata.point_labels.append(ti) self.graph.plot_widget.addItem(ti)
def splash_screen(): path = pkg_resources.resource_filename(__name__, "icons/tods-splash-screen.png") pm = QPixmap(path) version = pkg_resources.get_distribution("tods").version size = 18 if len(version) < 5 else 16 font = QFont("Helvetica") font.setPixelSize(size) font.setBold(True) font.setItalic(True) font.setLetterSpacing(QFont.AbsoluteSpacing, 2) metrics = QFontMetrics(font) br = metrics.boundingRect(version).adjusted(-5, 0, 5, 0) br.moveCenter(QPoint(440, 350)) p = QPainter(pm) p.setRenderHint(QPainter.Antialiasing) p.setRenderHint(QPainter.TextAntialiasing) p.setFont(font) p.setPen(QColor("#231F20")) p.drawText(br, Qt.AlignCenter, version) p.end() return pm, QRect(88, 193, 200, 20)
def __static_text_elided_cache( self, text: str, font: QFont, fontMetrics: QFontMetrics, elideMode: Qt.TextElideMode, width: int ) -> QStaticText: """ Return a `QStaticText` instance for depicting the text with the `font` """ try: return self.__static_text_lru_cache[text, font, elideMode, width] except KeyError: text = fontMetrics.elidedText(text, elideMode, width) st = QStaticText(text) st.prepare(QTransform(), font) # take a copy of the font for cache key key = text, QFont(font), elideMode, width self.__static_text_lru_cache[key] = st return st
def paintEvent(self, _event) -> None: painter = QStylePainter(self) option = QStyleOptionComboBox() self.initStyleOption(option) painter.drawComplexControl(QStyle.CC_ComboBox, option) foreground = self.currentData(Qt.ForegroundRole) if isinstance(foreground, (QBrush, QColor)): foreground = QBrush(foreground) if foreground.style() != Qt.NoBrush: # some styles take WindowText some just use current pen? option.palette.setBrush(QPalette.WindowText, foreground) option.palette.setBrush(QPalette.ButtonText, foreground) option.palette.setBrush(QPalette.Text, foreground) painter.setPen(QPen(foreground, painter.pen().widthF())) font = self.currentData(Qt.FontRole) if isinstance(font, QFont): option.fontMetrics = QFontMetrics(font) painter.setFont(font) painter.drawControl(QStyle.CE_ComboBoxLabel, option)
def __paintEventNoStyle(self): p = QPainter(self) opt = QStyleOptionToolButton() self.initStyleOption(opt) fm = QFontMetrics(opt.font) palette = opt.palette # highlight brush is used as the background for the icon and background # when the tab is expanded and as mouse hover color (lighter). brush_highlight = palette.highlight() foregroundrole = QPalette.ButtonText if opt.state & QStyle.State_Sunken: # State 'down' pressed during a mouse press (slightly darker). background_brush = brush_darker(brush_highlight, 110) foregroundrole = QPalette.HighlightedText elif opt.state & QStyle.State_MouseOver: background_brush = brush_darker(brush_highlight, 95) foregroundrole = QPalette.HighlightedText elif opt.state & QStyle.State_On: background_brush = brush_highlight foregroundrole = QPalette.HighlightedText else: # The default button brush. background_brush = palette.button() rect = opt.rect icon_area_rect = QRect(rect) icon_area_rect.setRight(int(icon_area_rect.height() * 1.26)) text_rect = QRect(rect) text_rect.setLeft(icon_area_rect.right() + 10) # Background (TODO: Should the tab button have native # toolbutton shape, drawn using PE_PanelButtonTool or even # QToolBox tab shape) # Default outline pen pen = QPen(palette.color(QPalette.Mid)) p.save() p.setPen(Qt.NoPen) p.setBrush(QBrush(background_brush)) p.drawRect(rect) # Draw the background behind the icon if the background_brush # is different. if not opt.state & QStyle.State_On: p.setBrush(brush_highlight) p.drawRect(icon_area_rect) # Line between the icon and text p.setPen(pen) p.drawLine(icon_area_rect.topRight(), icon_area_rect.bottomRight()) if opt.state & QStyle.State_HasFocus: # Set the focus frame pen and draw the border pen = QPen(QColor(FOCUS_OUTLINE_COLOR)) p.setPen(pen) p.setBrush(Qt.NoBrush) # Adjust for pen rect = rect.adjusted(0, 0, -1, -1) p.drawRect(rect) else: p.setPen(pen) # Draw the top/bottom border if self.position == QStyleOptionToolBox.OnlyOneTab or \ self.position == QStyleOptionToolBox.Beginning or \ self.selected & \ QStyleOptionToolBox.PreviousIsSelected: p.drawLine(rect.topLeft(), rect.topRight()) p.drawLine(rect.bottomLeft(), rect.bottomRight()) p.restore() p.save() text = fm.elidedText(opt.text, Qt.ElideRight, text_rect.width()) p.setPen(QPen(palette.color(foregroundrole))) p.setFont(opt.font) p.drawText(text_rect, int(Qt.AlignVCenter | Qt.AlignLeft) | \ int(Qt.TextSingleLine), text) if not opt.icon.isNull(): if opt.state & QStyle.State_Enabled: mode = QIcon.Normal else: mode = QIcon.Disabled if opt.state & QStyle.State_On: state = QIcon.On else: state = QIcon.Off icon_area_rect = icon_area_rect icon_rect = QRect(QPoint(0, 0), opt.iconSize) icon_rect.moveCenter(icon_area_rect.center()) opt.icon.paint(p, icon_rect, Qt.AlignCenter, mode, state) p.restore()
def set_text(self): metrics = QFontMetrics(self.font()) self.setText(metrics.elidedText(self.desc_text, Qt.ElideRight, self.width() - 15))
def __paintEventNoStyle(self): p = QPainter(self) opt = QStyleOptionToolButton() self.initStyleOption(opt) fm = QFontMetrics(opt.font) palette = opt.palette # highlight brush is used as the background for the icon and background # when the tab is expanded and as mouse hover color (lighter). brush_highlight = palette.highlight() if opt.state & QStyle.State_Sunken: # State 'down' pressed during a mouse press (slightly darker). background_brush = brush_darker(brush_highlight, 110) elif opt.state & QStyle.State_MouseOver: background_brush = brush_darker(brush_highlight, 95) elif opt.state & QStyle.State_On: background_brush = brush_highlight else: # The default button brush. background_brush = palette.button() rect = opt.rect icon_area_rect = QRect(rect) icon_area_rect.setRight(int(icon_area_rect.height() * 1.26)) text_rect = QRect(rect) text_rect.setLeft(icon_area_rect.right() + 10) # Background (TODO: Should the tab button have native # toolbutton shape, drawn using PE_PanelButtonTool or even # QToolBox tab shape) # Default outline pen pen = QPen(palette.color(QPalette.Mid)) p.save() p.setPen(Qt.NoPen) p.setBrush(QBrush(background_brush)) p.drawRect(rect) # Draw the background behind the icon if the background_brush # is different. if not opt.state & QStyle.State_On: p.setBrush(brush_highlight) p.drawRect(icon_area_rect) # Line between the icon and text p.setPen(pen) p.drawLine(icon_area_rect.topRight(), icon_area_rect.bottomRight()) if opt.state & QStyle.State_HasFocus: # Set the focus frame pen and draw the border pen = QPen(QColor(FOCUS_OUTLINE_COLOR)) p.setPen(pen) p.setBrush(Qt.NoBrush) # Adjust for pen rect = rect.adjusted(0, 0, -1, -1) p.drawRect(rect) else: p.setPen(pen) # Draw the top/bottom border if self.position == QStyleOptionToolBox.OnlyOneTab or \ self.position == QStyleOptionToolBox.Beginning or \ self.selected & \ QStyleOptionToolBox.PreviousIsSelected: p.drawLine(rect.topLeft(), rect.topRight()) p.drawLine(rect.bottomLeft(), rect.bottomRight()) p.restore() p.save() text = fm.elidedText(opt.text, Qt.ElideRight, text_rect.width()) p.setPen(QPen(palette.color(QPalette.ButtonText))) p.setFont(opt.font) p.drawText(text_rect, int(Qt.AlignVCenter | Qt.AlignLeft) | \ int(Qt.TextSingleLine), text) if not opt.icon.isNull(): if opt.state & QStyle.State_Enabled: mode = QIcon.Normal else: mode = QIcon.Disabled if opt.state & QStyle.State_On: state = QIcon.On else: state = QIcon.Off icon_area_rect = icon_area_rect icon_rect = QRect(QPoint(0, 0), opt.iconSize) icon_rect.moveCenter(icon_area_rect.center()) opt.icon.paint(p, icon_rect, Qt.AlignCenter, mode, state) p.restore()