def createAttributePixmap(char, background=Qt.black, color=Qt.white): """ Create a QIcon with a given character. The icon is 13 pixels high and wide. :param char: The character that is printed in the icon :type char: str :param background: the background color (default: black) :type background: QColor :param color: the character color (default: white) :type color: QColor :rtype: QIcon """ icon = QtGui.QIcon() for size in (13, 16, 18, 20, 22, 24, 28, 32, 64): pixmap = QtGui.QPixmap(size, size) pixmap.fill(Qt.transparent) painter = QtGui.QPainter() painter.begin(pixmap) painter.setRenderHints(painter.Antialiasing | painter.TextAntialiasing | painter.SmoothPixmapTransform) painter.setPen(background) painter.setBrush(background) margin = 1 + size // 16 text_margin = size // 20 rect = QtCore.QRectF(margin, margin, size - 2 * margin, size - 2 * margin) painter.drawRoundedRect(rect, 30.0, 30.0, Qt.RelativeSize) painter.setPen(color) font = painter.font() # type: QtGui.QFont font.setPixelSize(size - 2 * margin - 2 * text_margin) painter.setFont(font) painter.drawText(rect, Qt.AlignCenter, char) painter.end() icon.addPixmap(pixmap) return icon
def write_image(cls, filename, scene): # export via svg to temp file then print that # NOTE: can't use NamedTemporaryFile with delete = True # (see https://bugs.python.org/issue14243) fd, tmpname = tempfile.mkstemp(suffix=".svg") os.close(fd) try: SvgFormat.write_image(tmpname, scene) with open(tmpname, "rb") as f: svgcontents = f.read() finally: os.unlink(tmpname) svgrend = QtSvg.QSvgRenderer(QtCore.QByteArray(svgcontents)) vbox = svgrend.viewBox() if not vbox.isValid(): size = svgrend.defaultSize() else: size = vbox.size() writer = QtGui.QPdfWriter(filename) writer.setPageSizeMM(QtCore.QSizeF(size) * 0.282) painter = QtGui.QPainter(writer) svgrend.render(painter) painter.end() del svgrend del painter
def _get_buffer(size, filename): buffer = QtGui.QPdfWriter(filename) dpi = QtGui.QDesktopWidget().logicalDpiX() buffer.setResolution(dpi) buffer.setPageMargins(QMarginsF(0, 0, 0, 0)) buffer.setPageSizeMM( QtCore.QSizeF(size.width(), size.height()) / dpi * 25.4) return buffer
def setText(self, text): text = self._text = QtGui.QStaticText(text or '') text.setPerformanceHint(text.AggressiveCaching) option = QtGui.QTextOption() option.setWrapMode(QtGui.QTextOption.NoWrap) text.setTextOption(option) scene = self.scene() scene.invalidate(layers=scene.BackgroundLayer)
def selectable(self, value): if value: self._form.label.setTextInteractionFlags( QtCore.Qt.TextSelectableByMouse) self._form.label.setCursor(QtGui.QCursor(QtCore.Qt.IBeamCursor)) else: self._form.label.setTextInteractionFlags( QtCore.Qt.NoTextInteraction) self._form.label.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
def _get_buffer(size, filename): buffer = QtGui.QPdfWriter(filename) dpi = int(QApplication.primaryScreen().logicalDotsPerInch()) buffer.setResolution(dpi) buffer.setPageMargins(QMarginsF(0, 0, 0, 0)) pagesize = QtCore.QSizeF(size.width(), size.height()) / dpi * 25.4 buffer.setPageSize( QtGui.QPageSize(pagesize, QtGui.QPageSize.Millimeter)) return buffer
def _get_target(scene, painter, buffer, source): try: brush = scene.backgroundBrush() if brush.style() == QtCore.Qt.NoBrush: brush = QtGui.QBrush(scene.palette().color(QtGui.QPalette.Base)) except AttributeError: # not a QGraphicsView/Scene brush = QtGui.QBrush(QtCore.Qt.white) painter.fillRect(buffer.rect(), brush) return QtCore.QRectF(0, 0, source.width(), source.height())
def paint(self, painter, option, index): options = QStyleOptionViewItem(option) self.initStyleOption(options, index) style = QApplication.style( ) if options.widget is None else options.widget.style() doc = QtGui.QTextDocument() doc.setHtml(options.text) options.text = "" style.drawControl(QStyle.CE_ItemViewItem, options, painter) ctx = QtGui.QAbstractTextDocumentLayout.PaintContext() if options.state & QStyle.State_Selected: ctx.palette.setColor( QtGui.QPalette.Text, options.palette.color(QtGui.QPalette.Active, QtGui.QPalette.HighlightedText)) textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options) painter.save() painter.translate(textRect.topLeft()) painter.setClipRect(textRect.translated(-textRect.topLeft())) doc.documentLayout().draw(painter, ctx) painter.restore()
def write_image(cls, filename, scene): try: scene = scene.scene() scenerect = scene.sceneRect() # preserve scene bounding rectangle viewrect = scene.views()[0].sceneRect() scene.setSceneRect(viewrect) backgroundbrush = scene.backgroundBrush( ) # preserve scene background brush scene.setBackgroundBrush(QtCore.Qt.white) exporter = cls._get_exporter() cls._export(exporter(scene), filename) scene.setBackgroundBrush( backgroundbrush) # reset scene background brush scene.setSceneRect(scenerect) # reset scene bounding rectangle except Exception: if isinstance(scene, (QGraphicsScene, QGraphicsView)): rect = scene.sceneRect() elif isinstance(scene, QWidget): rect = scene.rect() rect = rect.adjusted(-15, -15, 15, 15) buffer = cls._get_buffer(rect.size(), filename) painter = QtGui.QPainter() painter.begin(buffer) painter.setRenderHint(QtGui.QPainter.Antialiasing) target = cls._get_target(scene, painter, buffer, rect) try: scene.render(painter, target, rect) except TypeError: scene.render( painter) # QWidget.render() takes different params painter.end() cls._save_buffer(buffer, filename)
def group_model(rowgroups, columngroups): model = QtGui.QStandardItemModel() for key, values in rowgroups: item = standarditem_from(key) values = [standarditem_from(value) for value in values] item.appendRows(values) model.addRow(item)
def render_as_png(self, filename): png = self.__transparent_png() painter = QtGui.QPainter(png) painter.setRenderHint(QtGui.QPainter.Antialiasing, 1) self.scene.render(painter, QRectF(0, 0, 50, 50), QRectF(-25, -25, 50, 50)) painter.end() png.save(filename)
def sizeHint(self, option, index): options = QStyleOptionViewItem(option) self.initStyleOption(options, index) doc = QtGui.QTextDocument() doc.setHtml(options.text) doc.setTextWidth(options.rect.width()) return QtCore.QSize(doc.idealWidth(), doc.size().height())
def __init__(self, parent=None): super(AbstractGLWidget, self).__init__(parent) self.image_2_display = [] self.textures = [] self.setMouseTracking(True) self.zoom = 0.0 self._mouseX = 0.0 self._mouseY = 0.0 #These variable are updated everytime the opengl scene is rendered #and a mouse button is down self._glX = 0.0 self._glY = 0.0 self._glZ = 0.0 #Last mouse opengl calculated position #This variable is updated everytime the opengl scene is rendered #and a mouse button is down self._mouse_pressed = False self._mouse_leftbtn_pressed = False self._mouse_clicked_event = None # store the event variable of the mouse click event self._mouse_dblclicked_event = None # store the event variable of the mouse double click event self._mouse_move_event = None # store the event variable of the mouse move event self._last_mouse_gl_pos = None self._lastGlX = 0.0 #Last self._lastGlY = 0.0 self._move_img = False # flag used to move the image with the mouse click button self._width = 1.0 self._height = 1.0 self._x = 0 self._y = 0 self.img_width = 1 self.img_height = 1 self._rotateZ = 0 self._rotateX = 0 self._mouseStartDragPoint = None # Message to show on the left corner of the screen self._helpText = None self.setMinimumHeight(100) self.setMinimumWidth(100) self._point = None self._pending_frames = [] self._tmp_msg = None self._font = QtGui.QFont() self._font.setPointSize(conf.PYFORMS_CONTROLPLAYER_FONT)
def row_item(display_value, item_values=None): """Generate a cell item for a given row.""" if not item_values: item_values = {} item = QtGui.QStandardItem() item.setData(display_value, Qt.DisplayRole) for role, value in item_values.items(): item.setData(value, role) return item
def paint(self, painter, option, index): painter.save() self.drawBackground(painter, option, index) ratio = index.data(TableBarItem.BarRole) if isinstance(ratio, float): if math.isnan(ratio): ratio = None color = None if ratio is not None: if self.color_schema is not None: class_ = index.data(TableClassValueRole) if isinstance(class_, Orange.data.Value) and \ class_.variable.is_discrete and \ not math.isnan(class_): color = self.color_schema[int(class_)] else: color = index.data(self.BarColorRole) if color is None: color = self.color rect = option.rect if ratio is not None: pw = 5 hmargin = 3 + pw / 2 # + half pen width for the round line cap vmargin = 1 textoffset = pw + vmargin * 2 baseline = rect.bottom() - textoffset / 2 width = (rect.width() - 2 * hmargin) * ratio painter.save() painter.setRenderHint(QtGui.QPainter.Antialiasing) painter.setPen(QtGui.QPen(QtGui.QBrush(color), pw, Qt.SolidLine, Qt.RoundCap)) line = QtCore.QLineF( rect.left() + hmargin, baseline, rect.left() + hmargin + width, baseline ) painter.drawLine(line) painter.restore() text_rect = rect.adjusted(0, 0, 0, -textoffset) else: text_rect = rect text = str(index.data(Qt.DisplayRole)) self.drawDisplay(painter, option, text_rect, text) painter.restore()
def standarditem_from_rowgroup(rowgroup): item = QtGui.QStandardItem(rowgroup.name) icon, _ = gui.attributeItem(rowgroup.var) item.setIcon(icon) item.setToolTip(guiutils.variable_tooltip(rowgroup.var)) item.setData(rowgroup, Qt.UserRole) item.setFlags(item.flags() & ~Qt.ItemIsEditable) children = [guiutils.standarditem_from(val) for val in rowgroup.values] item.appendRows(children) return item
def standarditem_from_columngroup(colgroup): item = QtGui.QStandardItem(colgroup.name) # item.setIcon(pkg_path('columnset.svg')) item.setToolTip("Split by column label: '{!s}'" .format(escape(colgroup.name))) item.setFlags(item.flags() & ~Qt.ItemIsEditable) item.setData(colgroup, Qt.UserRole) children = [guiutils.standarditem_from(val) for val in colgroup.values] item.appendRows(children) return item
def _setup_delegate_discrete(self, delegate): colors = [QtGui.QColor(*rgb) for rgb in self.class_var.colors] fmt = [] if self.show_probabilities: fmt.append(" : ".join("{{dist[{}]:.2f}}".format(i) for i in sorted(self.selected_classes))) if self.show_predictions: fmt.append("{value!s}") delegate.setFormat(" \N{RIGHTWARDS ARROW} ".join(fmt)) if self.draw_dist and colors is not None: delegate.setColors(colors) return delegate
def __init__(self, project=None): """ :param project: project where this board belongs :type project: pycontrolgui.models.project.Project """ BaseWidget.__init__(self, 'Board') self.layout().setContentsMargins(5, 10, 5, 5) self._name = ControlText('Box name') self._serial_port = ControlCombo('Serial port') self._refresh_serials = ControlButton( '', icon=QtGui.QIcon(conf.REFRESH_SMALL_ICON), default=self.__refresh_serials_pressed, helptext="Press here to refresh the list of available devices.") self._log_btn = ControlButton('Console') self._active_bnc = ControlCheckBoxList('BNC') self._active_wired = ControlCheckBoxList('Wired') self._active_behavior = ControlCheckBoxList('Behavior') self._loadports_btn = ControlButton('Load board info') self._netport = ControlNumber('Net port', default=36000 + len(project.boards), minimum=36000, maximum=36100) self._events = ControlList('Events', readonly=True) self._inputchannels = ControlList('Input channels', readonly=True) self._outputchannels = ControlList('Output channels', readonly=True) self._saved_serial_port = None Board.__init__(self, project) self._formset = [ '_name', ('_serial_port', '_refresh_serials'), '_netport', '_log_btn', '=', '_loadports_btn', { 'Ports': [ 'Enabled or disable ports', '_active_bnc', '_active_wired', '_active_behavior', ], 'Events': ['_events'], 'Input ch.': ['_inputchannels'], 'Output ch.': ['_outputchannels'] } ] self._name.changed_event = self.__name_changed_evt self._loadports_btn.value = self.__load_bpod_ports self._fill_serial_ports()
def __getitem__(self, key): if not self: for tpe, char, col in ((vartype(ContinuousVariable("c")), "N", (202, 0, 32)), (vartype(DiscreteVariable("d")), "C", (26, 150, 65)), (vartype(StringVariable("s")), "S", (0, 0, 0)), (vartype(TimeVariable("t")), "T", (68, 170, 255)), (-1, "?", (128, 128, 128))): self[tpe] = createAttributePixmap(char, QtGui.QColor(*col)) if key not in self: key = vartype(key) if isinstance(key, Variable) else -1 return super().__getitem__(key)
def __init__(self, parent=None, color=QtGui.QColor(255, 170, 127), color_schema=None): """ :param QObject parent: Parent object. :param QColor color: Default color of the distribution bar. :param color_schema: If not None it must be an instance of :class:`OWColorPalette.ColorPaletteGenerator` (note: this parameter, if set, overrides the ``color``) :type color_schema: :class:`OWColorPalette.ColorPaletteGenerator` """ super().__init__(parent) self.color = color self.color_schema = color_schema
def clear(self): """ Clear the widget/model (same as ``setModel(None)``). """ if self.__model is not None: self.values_view.selectionModel().clearSelection() self.values_view.selectionModel().selectionChanged.disconnect( self.__onSelectionChanged) self.values_view.setModel(None) self.labels_combo.setModel( QtGui.QStandardItemModel(self.labels_combo)) self.__currentIndex = -1 self.__selections = {} self.__model = None
def mousePressEvent(self, event): self._selection = [] if event.button() == Qt.LeftButton: if self.is_animating: self.is_animating = False return # Save the current selection and restore it on mouse{Move,Release} self._clicked_node = self.itemAt(event.pos()) if event.modifiers() & Qt.ShiftModifier: self._selection = self.scene().selectedItems() # On right mouse button, switch to pan mode elif event.button() == Qt.RightButton: self.setDragMode(self.ScrollHandDrag) # Forge left mouse button event event = QtGui.QMouseEvent(event.type(), event.pos(), event.globalPos(), Qt.LeftButton, event.buttons(), event.modifiers()) super().mousePressEvent(event) # Reselect the selection that had just been discarded for node in self._selection: node.setSelected(True)
def _update_prediction_delegate(self): """Update the predicted probability visibility state""" delegate = PredictionsItemDelegate() colors = None if self.class_var is not None: if self.class_var.is_discrete: colors = [QtGui.QColor(*rgb) for rgb in self.class_var.colors] dist_fmt = "" pred_fmt = "" if self.show_probabilities: decimals = 2 float_fmt = "{{dist[{}]:.{}f}}" dist_fmt = " : ".join( float_fmt.format(i, decimals) for i in range(len(self.class_var.values)) if i in self.selected_classes) if self.show_predictions: pred_fmt = "{value!s}" if pred_fmt and dist_fmt: fmt = dist_fmt + " \N{RIGHTWARDS ARROW} " + pred_fmt else: fmt = dist_fmt or pred_fmt else: assert isinstance(self.class_var, ContinuousVariable) fmt = "{{value:.{}f}}".format( self.class_var.number_of_decimals) delegate.setFormat(fmt) if self.draw_dist and colors is not None: delegate.setColors(colors) self.predictionsview.setItemDelegate(delegate) self.predictionsview.resizeColumnsToContents() if self.class_var is not None and self.class_var.is_discrete: proxy = self.predictionsview.model() if proxy is not None: proxy.setProbInd(numpy.array(self.selected_classes, dtype=int)) self._update_spliter()
def _fetch_indicators(self, progress=lambda val: None): """Background task for fetching indicators.""" progress(0) def row_item(display_value, item_values=None): """Generate a cell item for a given row.""" if not item_values: item_values = {} item = QtGui.QStandardItem() item.setData(display_value, Qt.DisplayRole) for role, value in item_values.items(): item.setData(value, role) return item progress(10) filter_ = self._main_widget.basic_indicator_filter() data = self._api.get_indicators(filter_=filter_) self._indicator_data = {ind["id"]: ind for ind in data} progress(70) indicators = [[""] + row for row in self._api.get_indicator_list(filter_=filter_)] model = QtGui.QStandardItemModel() model.setHorizontalHeaderLabels(indicators[0]) for row in indicators[1:]: search_string = " | ".join(row).lower() row_data = [row_item(item) for item in row] row_data[0].setData(search_string, TEXTFILTERROLE) row_data[1].setData(self._get_link(row[1]), gui.LinkRole) model.appendRow(row_data) progress(100) if QThread.currentThread() is not QCoreApplication.instance().thread(): model.moveToThread(QCoreApplication.instance().thread()) return model
def update_stats_model(self): # Update the results_model with up to date scores. # Note: The target class specific scores (if requested) are # computed as needed in this method. model = self.score_table.model # clear the table model, but preserving the header labels for r in reversed(range(model.rowCount())): model.takeRow(r) target_index = None if self.data is not None: class_var = self.data.domain.class_var if self.data.domain.has_discrete_class and \ self.class_selection != self.TARGET_AVERAGE: target_index = class_var.values.index(self.class_selection) else: class_var = None errors = [] has_missing_scores = False names = [] for key, slot in self.learners.items(): name = learner_name(slot.learner) names.append(name) head = QStandardItem(name) head.setData(key, Qt.UserRole) results = slot.results if results is not None and results.success: train = QStandardItem("{:.3f}".format( results.value.train_time)) train.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) train.setData(key, Qt.UserRole) test = QStandardItem("{:.3f}".format(results.value.test_time)) test.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) test.setData(key, Qt.UserRole) row = [head, train, test] else: row = [head] if isinstance(results, Try.Fail): head.setToolTip(str(results.exception)) head.setText("{} (error)".format(name)) head.setForeground(QtGui.QBrush(Qt.red)) if isinstance(results.exception, DomainTransformationError) \ and self.resampling == self.TestOnTest: self.Error.test_data_incompatible() self.Information.test_data_transformed.clear() else: errors.append("{name} failed with error:\n" "{exc.__class__.__name__}: {exc!s}".format( name=name, exc=slot.results.exception)) if class_var is not None and class_var.is_discrete and \ target_index is not None: if slot.results is not None and slot.results.success: ovr_results = results_one_vs_rest(slot.results.value, target_index) # Cell variable is used immediatelly, it's not stored # pylint: disable=cell-var-from-loop stats = [ Try(scorer_caller(scorer, ovr_results, target=1)) for scorer in self.scorers ] else: stats = None else: stats = slot.stats if stats is not None: for stat, scorer in zip(stats, self.scorers): item = QStandardItem() item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) if stat.success: item.setData(float(stat.value[0]), Qt.DisplayRole) else: item.setToolTip(str(stat.exception)) if scorer.name in self.score_table.shown_scores: has_missing_scores = True row.append(item) model.appendRow(row) # Resort rows based on current sorting header = self.score_table.view.horizontalHeader() model.sort(header.sortIndicatorSection(), header.sortIndicatorOrder()) self._set_comparison_headers(names) self.error("\n".join(errors), shown=bool(errors)) self.Warning.scores_not_computed(shown=has_missing_scores)
def _update_stats_model(self): # Update the results_model with up to date scores. # Note: The target class specific scores (if requested) are # computed as needed in this method. model = self.view.model() # clear the table model, but preserving the header labels for r in reversed(range(model.rowCount())): model.takeRow(r) target_index = None if self.data is not None: class_var = self.data.domain.class_var if self.data.domain.has_discrete_class and \ self.class_selection != self.TARGET_AVERAGE: target_index = class_var.values.index(self.class_selection) else: class_var = None errors = [] has_missing_scores = False for key, slot in self.learners.items(): name = learner_name(slot.learner) head = QStandardItem(name) head.setData(key, Qt.UserRole) if isinstance(slot.results, Try.Fail): head.setToolTip(str(slot.results.exception)) head.setText("{} (error)".format(name)) head.setForeground(QtGui.QBrush(Qt.red)) errors.append("{name} failed with error:\n" "{exc.__class__.__name__}: {exc!s}".format( name=name, exc=slot.results.exception)) row = [head] if class_var is not None and class_var.is_discrete and \ target_index is not None: if slot.results is not None and slot.results.success: ovr_results = results_one_vs_rest(slot.results.value, target_index) # Cell variable is used immediatelly, it's not stored # pylint: disable=cell-var-from-loop stats = [ Try(scorer_caller(scorer, ovr_results)) for scorer in self.scorers ] else: stats = None else: stats = slot.stats if stats is not None: for stat in stats: item = QStandardItem() if stat.success: item.setText("{:.3f}".format(stat.value[0])) else: item.setToolTip(str(stat.exception)) has_missing_scores = True row.append(item) model.appendRow(row) self.error("\n".join(errors), shown=bool(errors)) self.Warning.scores_not_computed(shown=has_missing_scores)
def _get_buffer(size, filename): return QtGui.QPixmap(int(size.width()), int(size.height()))
# !/usr/bin/python3 # -*- coding: utf-8 -*- SETTINGS_PRIORITY = 10 import os, AnyQt from pyforms import conf if conf.PYFORMS_MODE == 'GUI': from AnyQt import QtGui def path(filename): return os.path.join(os.path.dirname(__file__), 'icons', filename) PYFORMS_ICON_VIDEOPLAYER_PAUSE_PLAY = QtGui.QIcon() PYFORMS_ICON_VIDEOPLAYER_PAUSE_PLAY.addPixmap(QtGui.QPixmap(path('play.png')), mode=QtGui.QIcon.Normal, state=QtGui.QIcon.Off) PYFORMS_ICON_VIDEOPLAYER_PAUSE_PLAY.addPixmap(QtGui.QPixmap(path('pause.png')), mode=QtGui.QIcon.Normal, state=QtGui.QIcon.On) PYFORMS_ICON_CODEEDITOR_SAVE = QtGui.QIcon(path('export.png')) PYFORMS_PIXMAP_EVENTTIMELINE_ZOOM_IN = QtGui.QPixmap(path('zoom_in.png')) PYFORMS_PIXMAP_EVENTTIMELINE_ZOOM_OUT = QtGui.QPixmap(path('zoom_out.png')) PYFORMS_ICON_EVENTTIMELINE_IMPORT = QtGui.QIcon(path('import.png')) PYFORMS_ICON_EVENTTIMELINE_EXPORT = QtGui.QIcon(path('export.png'))
def __init__(self): super().__init__() label = QtGui.QLabel("Hello, World!") self.controlArea.layout().addWidget( label, QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter)