def createInfoLayout(): info_layout = QVBoxLayout() ert = QLabel() ert.setAlignment(Qt.AlignHCenter) title_font = QFont() title_font.setPointSize(40) ert.setFont(title_font) ert.setText("ERT") info_layout.addWidget(ert) info_layout.addStretch(1) ert_title = QLabel() ert_title.setAlignment(Qt.AlignHCenter) ert_title.setText("Ensemble based Reservoir Tool") info_layout.addWidget(ert_title) version = QLabel() version.setAlignment(Qt.AlignHCenter) version.setText( "Versions: ecl:%s res:%s ert:%s" % (ecl.__version__, res.__version__, ert_gui.__version__)) info_layout.addWidget(version) info_layout.addStretch(5) return info_layout
def editor_bot(qtbot): """Editorstack pytest fixture.""" text = (" 123\n" "line 1\n" "line 2\n" "line 3\n" "line 4") # a newline is added at end editor_stack = EditorStack(None, []) # Fix the area of the selection font = QFont("Courier New") font.setPointSize(10) editor_stack.set_default_font(font) editor_stack.setMinimumWidth(400) editor_stack.setMinimumHeight(400) editor_stack.set_find_widget(Mock()) editor_stack.set_io_actions(Mock(), Mock(), Mock(), Mock()) finfo = editor_stack.new(osp.join(LOCATION, "foo.py"), "utf-8", text) editor_stack.new(osp.join(LOCATION, "foo1.py"), "utf-8", text) editor_stack.new(osp.join(LOCATION, "foo2.py"), "utf-8", text) editor_stack.new(osp.join(LOCATION, "foo3.py"), "utf-8", text) main = MainMock(editor_stack) # Hide GUI # qtbot.addWidget(main) # return main, editor_stack, finfo.editor, qtbot # Show GUI main.show() yield main, editor_stack, finfo.editor, qtbot main.destroy()
def get_font(section='appearance', option='font', font_size_delta=0): """Get console font properties depending on OS and user options""" font = FONT_CACHE.get((section, option)) if font is None: families = CONF.get(section, option+"/family", None) if families is None: return QFont() family = get_family(families) weight = QFont.Normal italic = CONF.get(section, option+'/italic', False) if CONF.get(section, option+'/bold', False): weight = QFont.Bold size = CONF.get(section, option+'/size', 9) + font_size_delta font = QFont(family, size, weight) font.setItalic(italic) FONT_CACHE[(section, option)] = font size = CONF.get(section, option+'/size', 9) + font_size_delta font.setPointSize(size) return font
def make_font(font_size, is_bold=False): """creates a QFont""" font = QFont() font.setPointSize(font_size) if is_bold: font.setBold(is_bold) return font
def format_pg_plotitem(plot, x_lim, y_lim, x_range=None, y_range=None): ''' Applies a standard format to a pyqtgraph chart. :param plot: the plot item. :param x_lim: the x axis limits. :param y_lim: the y axis limits. :param x_range: the visible x limits. :param y_range: the visible y limits. ''' label_font = QFont() label_font.setPointSize(9) label_font.setFamily('DejaVu Sans') for name in ['left', 'right', 'bottom', 'top']: plot.getAxis(name).setTickFont(label_font) plot.showGrid(x=True, y=True, alpha=0.5) plot.disableAutoRange() plot.setLimits(xMin=x_lim[0], xMax=x_lim[1], yMin=y_lim[0], yMax=y_lim[1]) plot.setXRange(*x_lim, padding=0.0) if x_range is None: plot.setXRange(*x_lim, padding=0.0) else: plot.setXRange(*x_range, padding=0.0) if y_range is None: plot.setYRange(*y_lim, padding=0.0) else: plot.setYRange(*y_range, padding=0.0) plot.setDownsampling(ds=False) plot.layout.setContentsMargins(10, 20, 30, 20)
def add_series(self, chan_info): glw = self.findChild(pg.GraphicsLayoutWidget) new_plot = glw.addPlot(row=len(self.rasters), col=0) # Appearance settings my_theme = THEMES[self.plot_config['theme']] self.plot_config['color_iterator'] = ( self.plot_config['color_iterator'] + 1) % len( my_theme['pencolors']) pen_color = QColor( my_theme['pencolors'][self.plot_config['color_iterator']]) # Create PlotCurveItem for latest spikes (bottom row) and slower-updating old spikes (upper rows) pcis = [] for pci_ix in range(2): pci = pg.PlotCurveItem(parent=new_plot, connect='pairs') pci.setPen(pen_color) new_plot.addItem(pci) pcis.append(pci) # Create text for displaying firing rate. Placeholder text is channel label. frate_annotation = pg.TextItem(text=chan_info['label'], color=(255, 255, 255)) frate_annotation.setPos(0, self.plot_config['y_range']) my_font = QFont() my_font.setPointSize(24) frate_annotation.setFont(my_font) new_plot.addItem(frate_annotation) # Store information self.rasters[chan_info['label']] = { 'plot': new_plot, 'old': pcis[0], 'latest': pcis[1], 'line_ix': len(self.rasters), 'chan_id': chan_info['chan'], 'frate_item': frate_annotation } self.clear()
def setFont(self, font=None): if font is None: font = QFont() # default font font.setFamily('Courier New') font.setPointSize(11) self.find.txtSearch.setFont(font) self.tree.setFont(font) self.form.setFont(font)
def __init__(self, parent=None): """ very similar to: https://stackoverflow.com/questions/40002373/qscintilla-based-text-editor-in-pyqt5-with-clickable-functions-and-variables """ super(SimplePythonEditorWidget, self).__init__(parent) # Set the default font font = QFont() font.setFamily('Courier') font.setFixedPitch(True) font.setPointSize(10) self.setFont(font) self.setMarginsFont(font) self.set_font(font) self.setMarginLineNumbers(0, True) self.setMarginsBackgroundColor(QColor("#cccccc")) # Clickable margin 1 for showing markers self.setMarginSensitivity(1, True) if qt_version == 'pyqt4': self.connect(self, QtCore.SIGNAL('marginClicked(int, int, Qt::KeyboardModifiers)'), self.on_margin_clicked) else: self.marginClicked.connect(self.on_margin_clicked) self.markerDefine(Qsci.QsciScintilla.RightArrow, self.ARROW_MARKER_NUM) self.setMarkerBackgroundColor(QColor("#ee1111"), self.ARROW_MARKER_NUM) # Brace matching: enable for a brace immediately before or after # the current position self.setBraceMatching(Qsci.QsciScintilla.SloppyBraceMatch) # Current line visible with special background color self.setCaretLineVisible(True) self.setCaretLineBackgroundColor(QColor("#ffe4e4")) # Set Python lexer # Set style for Python comments (style number 1) to a fixed-width # courier. lexer = Qsci.QsciLexerPython() lexer.setDefaultFont(font) self.setLexer(lexer) if qt_version == 'pyqt4': self.SendScintilla(Qsci.QsciScintilla.SCI_STYLESETFONT, 1, 'Courier') else: font_style = bytearray(str.encode("Courier")) self.SendScintilla(Qsci.QsciScintilla.SCI_STYLESETFONT, 1, font_style) # Don't want to see the horizontal scrollbar at all # Use raw message to Scintilla here (all messages are documented # here: http://www.scintilla.org/ScintillaDoc.html) self.SendScintilla(Qsci.QsciScintilla.SCI_SETHSCROLLBAR, 0)
def populate_tree(self): """Create each item (and associated data) in the tree""" if not len(self.data): warn_item = QTreeWidgetItem(self) warn_item.setData(0, Qt.DisplayRole, "No results to show.") warn_item.setFirstColumnSpanned(True) warn_item.setTextAlignment(0, Qt.AlignCenter) font = warn_item.font(0) font.setStyle(QFont.StyleItalic) warn_item.setFont(0, font) return try: monospace_font = self.window().editor.get_plugin_font() except AttributeError: # If run standalone for testing monospace_font = QFont("Courier New") monospace_font.setPointSize(10) for testcase in self.data: testcase_item = QTreeWidgetItem(self) testcase_item.setData( 1, Qt.DisplayRole, "{0}.{1}".format( testcase.get("classname"), testcase.get("name"))) testcase_item.setData( 3, Qt.DisplayRole, float(testcase.get("time")) * 1e3) if len(testcase): test_error = testcase[0] status = test_error.tag testcase_item.setData(0, Qt.DisplayRole, status) color = COLORS[status] for col in range(self.columnCount()): testcase_item.setBackground(col, color) type_ = test_error.get("type") message = test_error.get("message") if type_ and message: text = "{0}: {1}".format(type_, message) elif type_: text = type_ else: text = message testcase_item.setData(2, Qt.DisplayRole, text) text = test_error.text if text: for line in text.rstrip().split("\n"): error_content_item = QTreeWidgetItem(testcase_item) error_content_item.setData( 0, Qt.DisplayRole, line) error_content_item.setFirstColumnSpanned(True) error_content_item.setFont(0, monospace_font) else: testcase_item.setData(0, Qt.DisplayRole, "ok")
def changeEvent(self, event): if event.type() == QEvent.FontChange: fontsize = self.app.font().pointSize() # labels self.lb_machsht.label.setStyleSheet('QLabel{font-size: ' + str(fontsize + 35) + 'pt;}') self.lb_curr.setStyleSheet('QLabel{background-color: ' + self.app_color + ';' 'font-size: ' + str(fontsize + 35) + 'pt;}') self.lb_lifetime.setStyleSheet('QLabel{font-size: ' + str(fontsize + 35) + 'pt;}') self.tune_mon.lb_tunefrach.setStyleSheet('QLabel{font-size: ' + str(fontsize + 35) + 'pt;}') self.tune_mon.lb_tunefracv.setStyleSheet('QLabel{font-size: ' + str(fontsize + 35) + 'pt;}') self._gbox_siriusintlk.setStyleSheet('QGroupBox{font-size: ' + str(fontsize + 2) + 'pt;' 'font-weight: bold;}') self._gbox_injsyssts.setStyleSheet('QGroupBox{font-size: ' + str(fontsize + 2) + 'pt;' 'font-weight: bold;}') self._gbox_sofbloop.setStyleSheet('QGroupBox{font-size: ' + str(fontsize + 2) + 'pt;' 'font-weight: bold;}') self._gbox_bbbloop.setStyleSheet('QGroupBox{font-size: ' + str(fontsize + 2) + 'pt;' 'font-weight: bold;}') # graph graph_fontsize = fontsize + 2 for ax in self.curr_graph.getPlotItem().axes.values(): sty = ax['item'].labelStyle sty['font-size'] = str(graph_fontsize) + 'pt' ax['item'].setLabel(text=None, **sty) font = QFont() font.setPointSize(graph_fontsize) self.curr_graph.plotItem.getAxis('bottom').setStyle( tickTextOffset=5, autoExpandTextSpace=False, tickTextWidth=80, tickFont=font) self.curr_graph.plotItem.getAxis('left').setStyle( tickTextOffset=5, autoExpandTextSpace=False, tickTextWidth=80, tickFont=font) self.ensurePolished()
def get_gauge(self, parent, macros): aux = [] for k, v in macros.items(): aux.append('{}\t{}\n'.format(k, v)) tooltip = ''.join(aux) width = 320 height = 100 frame = QFrame(parent) frame.setGeometry(QRect(10, 10, width, height)) frame.setMinimumSize(width, height) frame.setFrameShape(QFrame.StyledPanel) frame.setFrameShadow(QFrame.Raised) frame.setObjectName("frame") brush = QBrush(QColor(180, 180, 180)) brush.setStyle(Qt.NoBrush) alarmRec = PyDMDrawingRectangle(frame) alarmRec.channel = "ca://{}".format(macros.get('ALARM', None)) alarmRec.setGeometry(QRect(0, 0, width, height)) alarmRec.setToolTip(tooltip) alarmRec.setProperty("alarmSensitiveContent", True) alarmRec.setProperty("brush", brush) alarmRec.setObjectName("alarmRec") # alarmRec.setStyleSheet("margin:5px; border:3px solid rgb(0, 0, 0);") lblName = QLabel(frame) lblName.setGeometry(QRect(width * 0.05, 50, width - width * 0.05, 20)) font = QFont() font.setPointSize(12) lblName.setFont(font) lblName.setAlignment(Qt.AlignCenter) lblName.setText("{}".format(macros.get('DISP', None))) lblName.setObjectName("lblName") lblName.setToolTip(tooltip) lblVal = PyDMLabel(frame) lblVal.setGeometry(QRect(width * 0.05, 10, width - width * 0.05, 30)) font = QFont() font.setPointSize(18) lblVal.setFont(font) lblVal.setToolTip(tooltip) lblVal.setAlignment(Qt.AlignCenter) lblVal.setProperty("showUnits", False) lblVal.setObjectName("lblVal") lblVal.channel = "ca://{}".format(macros.get('PV', None)) lblVal.precisionFromPV = False lblVal.precision = 2 if self.macros.get('FORMAT', '') == 'EXP': lblVal.displayFormat = PyDMLabel.DisplayFormat.Exponential return frame
def get_gauge(self, parent, pv_info: PVInfo): tooltip = "".join( [f"{key}\t{value}\n" for key, value in pv_info.__dict__.items()] ) width = 320 height = 100 frame = QFrame(parent) frame.setGeometry(QRect(10, 10, width, height)) frame.setMinimumSize(width, height) frame.setFrameShape(QFrame.StyledPanel) frame.setFrameShadow(QFrame.Raised) frame.setObjectName("frame") brush = QBrush(QColor(180, 180, 180)) brush.setStyle(Qt.NoBrush) alarmRec = PyDMDrawingRectangle(frame) alarmRec.channel = "ca://{}".format(pv_info.ALARM) alarmRec.setGeometry(QRect(0, 0, width, height)) alarmRec.setToolTip(tooltip) alarmRec.setProperty("alarmSensitiveContent", True) alarmRec.setProperty("brush", brush) alarmRec.setObjectName("alarmRec") # alarmRec.setStyleSheet("margin:5px; border:3px solid rgb(0, 0, 0);") lblName = QLabel(frame) lblName.setGeometry(QRect(width * 0.05, 50, width - width * 0.05, 20)) font = QFont() font.setPointSize(12) lblName.setFont(font) lblName.setAlignment(Qt.AlignCenter) lblName.setText("{}".format(pv_info.DISP)) lblName.setObjectName("lblName") lblName.setToolTip(tooltip) lblVal = PyDMLabel(frame) lblVal.setGeometry(QRect(width * 0.05, 10, width - width * 0.05, 30)) font = QFont() font.setPointSize(18) lblVal.setFont(font) lblVal.setToolTip(tooltip) lblVal.setAlignment(Qt.AlignCenter) lblVal.setProperty("showUnits", False) lblVal.setObjectName("lblVal") lblVal.channel = "ca://{}".format(pv_info.PV) lblVal.precisionFromPV = False lblVal.precision = 2 if self.macros().get("FORMAT", "") == "EXP": lblVal.displayFormat = PyDMLabel.DisplayFormat.Exponential return frame
def __init__(self, parent=None): super(SimplePythonEditorWidget, self).__init__(parent) # Set the default font font = QFont() font.setFamily('Courier') font.setFixedPitch(True) font.setPointSize(10) self.setFont(font) self.setMarginsFont(font) # Margin 0 is used for line numbers fontmetrics = QFontMetrics(font) self.setMarginsFont(font) self.setMarginWidth(0, fontmetrics.width("00000") + 6) self.setMarginLineNumbers(0, True) self.setMarginsBackgroundColor(QColor("#cccccc")) # Clickable margin 1 for showing markers self.setMarginSensitivity(1, True) self.connect( self, QtCore.SIGNAL( 'marginClicked(int, int, Qt::KeyboardModifiers)'), self.on_margin_clicked) self.markerDefine(Qsci.QsciScintilla.RightArrow, self.ARROW_MARKER_NUM) self.setMarkerBackgroundColor(QColor("#ee1111"), self.ARROW_MARKER_NUM) # Brace matching: enable for a brace immediately before or after # the current position self.setBraceMatching(Qsci.QsciScintilla.SloppyBraceMatch) # Current line visible with special background color self.setCaretLineVisible(True) self.setCaretLineBackgroundColor(QColor("#ffe4e4")) # Set Python lexer # Set style for Python comments (style number 1) to a fixed-width # courier. lexer = Qsci.QsciLexerPython() lexer.setDefaultFont(font) self.setLexer(lexer) self.SendScintilla(Qsci.QsciScintilla.SCI_STYLESETFONT, 1, 'Courier') # Don't want to see the horizontal scrollbar at all # Use raw message to Scintilla here (all messages are documented # here: http://www.scintilla.org/ScintillaDoc.html) self.SendScintilla(Qsci.QsciScintilla.SCI_SETHSCROLLBAR, 0)
def show_remux_cmd(self): ''' Pops the ffmpeg command into a message box ''' if self.__executor is not None and self.__executor.filter_complex_script_content is not None: msg_box = QMessageBox() font = QFont() font.setFamily("Consolas") font.setPointSize(8) msg_box.setFont(font) msg_box.setText( self.__executor.filter_complex_script_content.replace( ';', ';\n')) msg_box.setIcon(QMessageBox.Information) msg_box.setWindowTitle('Remux Script') msg_box.exec()
def __init__(self, parent=None): QWidget.__init__(self, parent=parent) self.titleLabel = QLabel() font = QFont() font.setPointSize(72) self.titleLabel.setFont(font) self.iconLabel = QLabel() layout = QHBoxLayout() layout.addWidget(self.iconLabel) layout.addWidget(self.titleLabel) print("boom") self.setTitle("Terminal") self.setIcon("terminal")
class StatusBarWidget(QWidget): """Status bar widget base.""" TIP = None def __init__(self, parent, statusbar, icon=None): """Status bar widget base.""" super(StatusBarWidget, self).__init__(parent) # Variables self.value = None # Widget self._icon = icon self._pixmap = icon.pixmap(QSize(16, 16)) if icon is not None else None self.label_icon = QLabel() if icon is not None else None self.label_value = QLabel() # Widget setup if icon is not None: self.label_icon.setPixmap(self._pixmap) # See spyder-ide/spyder#9044. self.text_font = QFont(get_font(option='font')) self.text_font.setPointSize(self.font().pointSize()) self.text_font.setBold(True) self.label_value.setAlignment(Qt.AlignRight) self.label_value.setFont(self.text_font) if self.TIP: self.setToolTip(self.TIP) self.label_value.setToolTip(self.TIP) # Layout layout = QHBoxLayout() if icon is not None: layout.addWidget(self.label_icon) layout.addWidget(self.label_value) layout.addSpacing(20) # Layout setup layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) # Setup statusbar.addPermanentWidget(self) def set_value(self, value): """Set formatted text value.""" self.value = value if self.isVisible(): self.label_value.setText(value)
def __init__(self, parent=None): super(EditorBase, self).__init__(parent) # linuxcnc defaults self.idle_line_reset = False # don't allow editing by default self.setReadOnly(True) # Set the default font font = QFont() font.setFamily('Courier') font.setFixedPitch(True) font.setPointSize(14) # Set custom gcode lexer self.lexer = GcodeLexer(self) self.lexer.setDefaultFont(font) self.setLexer(self.lexer) # Margin 0 is used for line numbers fontmetrics = QFontMetrics(font) self.setMarginsFont(font) self.setMarginWidth(0, fontmetrics.width("0") + 6) self.setMarginLineNumbers(0, True) self.setMarginsBackgroundColor(QColor("#cccccc")) # Clickable margin 1 for showing markers self.setMarginSensitivity(1, True) # setting marker margin width to zero make the marker highlight line self.setMarginWidth(1, 10) self.marginClicked.connect(self.on_margin_clicked) self.markerDefine(QsciScintilla.RightTriangle, self.ARROW_MARKER_NUM) # #ffe4e4 self.setMarkerBackgroundColor(QColor("slate"), self.ARROW_MARKER_NUM) # Brace matching: enable for a brace immediately before or after # the current position # self.setBraceMatching(QsciScintilla.SloppyBraceMatch) # Current line visible with special background color self.setCaretLineVisible(True) self.setCaretLineBackgroundColor(QColor("#ffe4e4")) # default gray background self.set_background_color('#C0C0C0') self.highlit = None
class StatusBarWidget(QWidget): """Status bar widget base.""" TIP = None def __init__(self, parent, statusbar, icon=None): """Status bar widget base.""" super(StatusBarWidget, self).__init__(parent) # Variables self.value = None # Widget self._icon = icon self._pixmap = icon.pixmap(QSize(16, 16)) if icon is not None else None self.label_icon = QLabel() if icon is not None else None self.label_value = QLabel() # Widget setup if icon is not None: self.label_icon.setPixmap(self._pixmap) self.text_font = QFont(get_font(option='font')) # See Issue #9044 self.text_font.setPointSize(self.font().pointSize()) self.text_font.setBold(True) self.label_value.setAlignment(Qt.AlignRight) self.label_value.setFont(self.text_font) if self.TIP: self.setToolTip(self.TIP) self.label_value.setToolTip(self.TIP) # Layout layout = QHBoxLayout() if icon is not None: layout.addWidget(self.label_icon) layout.addWidget(self.label_value) layout.addSpacing(20) # Layout setup layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) # Setup statusbar.addPermanentWidget(self) def set_value(self, value): """Set formatted text value.""" self.value = value if self.isVisible(): self.label_value.setText(value)
def set_font_size(self, font_size): """ Updates the font size of all objects in the PyDialog Parameters ---------- font_size : int the font size """ if self.font_size == font_size: return self.font_size = font_size font = QFont() font.setPointSize(font_size) self.setFont(font)
def text_font(): """Return the first monospace font for this system. The font is cached on first access. """ global _TEXT_FONT_CACHE if _TEXT_FONT_CACHE is None: fontdb = QFontDatabase() families = fontdb.families() for family in MONOSPACE: if family in families: _TEXT_FONT_CACHE = QFont(family) break _TEXT_FONT_CACHE.setPointSize(PT_SIZE) _TEXT_FONT_CACHE.setFixedPitch(True) return _TEXT_FONT_CACHE
def set_font_size(self, font_size): """ Updates the font size of the objects Parameters ---------- font_size : int the font size """ return if self.font_size == font_size: return self.font_size = font_size font = QFont() font.setPointSize(font_size) self.setFont(font)
def refreshEditorFont(self): """Taking the new default font and build a new lexer instance. Apply the new lexer to the editor. """ # Note that if you do not create a new lexer the # the font does not get applied/used. font = QFont() font.setFamily(self.default_font_name) font.setFixedPitch(True) font.setPointSize(14) self.lexer = GcodeLexer(self) self.lexer.setDefaultFont(font) self.setLexer(self.lexer) # rebuild gutter for new font self.setNumberGutter(self.lines()) # set the gutter font to be aligned to main font self.setMarginsFont(font)
def test(): import os.path as osp from spyderlib.utils.qthelpers import qapplication app = qapplication(test_time=5) shell = ExternalSystemShell(wdir=osp.dirname(__file__), light_background=False) app.aboutToQuit.connect(shell.finish_process) from qtpy.QtGui import QFont font = QFont() font.setPointSize(10) shell.shell.set_font(font) shell.shell.toggle_wrap_mode(True) shell.start_shell(False) shell.show() sys.exit(app.exec_())
def tuple_to_qfont(tup): """ Create a QFont from tuple: (family [string], size [int], italic [bool], bold [bool]) """ if not isinstance(tup, tuple) or len(tup) != 4 \ or not font_is_installed(tup[0]) \ or not isinstance(tup[1], int) \ or not isinstance(tup[2], bool) \ or not isinstance(tup[3], bool): return None font = QFont() family, size, italic, bold = tup font.setFamily(family) font.setPointSize(size) font.setItalic(italic) font.setBold(bold) return font
def test(): import os.path as osp from spyder.utils.qthelpers import qapplication app = qapplication(test_time=5) shell = ExternalSystemShell(wdir=osp.dirname(__file__), light_background=False) app.aboutToQuit.connect(shell.finish_process) from qtpy.QtGui import QFont font = QFont() font.setPointSize(10) shell.shell.set_font(font) shell.shell.toggle_wrap_mode(True) shell.start_shell(False) shell.show() sys.exit(app.exec_())
def main(): app = QApplication(sys.argv) if getattr(sys, 'frozen', False): iconPath = os.path.join(sys._MEIPASS, 'Icon.ico') else: iconPath = os.path.abspath( os.path.join(os.path.dirname('__file__'), '../icons/Icon.ico')) if os.path.exists(iconPath): app.setWindowIcon(QIcon(iconPath)) form = PyPolarmap(app) # setup the error handler global e_dialog e_dialog = QErrorMessage(form) e_dialog.setWindowModality(QtCore.Qt.WindowModal) font = QFont() font.setFamily("Consolas") font.setPointSize(8) e_dialog.setFont(font) form.show() app.exec_()
def __init__(self, chart, crest_factor, rms_level, headroom, x_min, x_max, y_min, y_max, on_x_range_change): self.idx = 0 self.__chart = chart self.__on_x_range_change = on_x_range_change self.__x_min = x_min self.__x_max = x_max self.__x_min.editingFinished.connect(self.__update_x_range) self.__x_max.editingFinished.connect(self.__update_x_range) self.__y_min = y_min self.__y_max = y_max self.__y_min.editingFinished.connect(self.__update_y_range) self.__y_max.editingFinished.connect(self.__update_y_range) self.__chart = chart label_font = QFont() fp = FontProperties() label_font.setPointSize(fp.get_size_in_points() * 0.7) label_font.setFamily(fp.get_name()) for name in ['left', 'right', 'bottom', 'top']: self.__chart.getPlotItem().getAxis(name).setTickFont(label_font) self.__chart.getPlotItem().showGrid(x=True, y=True, alpha=0.5) self.__chart.getPlotItem().disableAutoRange() self.__chart.getPlotItem().setLimits(xMin=0.0, xMax=1.0, yMin=-1.0, yMax=1.0) self.__chart.getPlotItem().setXRange(0, 1, padding=0.0) self.__chart.getPlotItem().setYRange(-1, 1, padding=0.0) self.__chart.getPlotItem().setDownsampling(ds=True, auto=True, mode='peak') self.__chart.getPlotItem().layout.setContentsMargins(10, 20, 30, 20) self.__chart.getPlotItem().sigXRangeChanged.connect( self.__propagate_x_range) self.__chart.getPlotItem().sigYRangeChanged.connect( self.__propagate_y_range) self.__headroom = headroom self.__rms_level = rms_level self.__crest_factor = crest_factor self.__signal = None self.__curve = None
def populate_tree(self): """Create each item (and associated data) in the tree.""" if not len(self.testresults): return _('No results to show.') try: monospace_font = self.window().editor.get_plugin_font() except AttributeError: # If run standalone for testing monospace_font = QFont("Courier New") monospace_font.setPointSize(10) for testresult in self.testresults: testcase_item = QTreeWidgetItem(self) testcase_item.setData(0, Qt.DisplayRole, testresult.status) testcase_item.setData(1, Qt.DisplayRole, testresult.name) fullname = '{0}.{1}'.format(testresult.module, testresult.name) testcase_item.setToolTip(1, fullname) testcase_item.setData(2, Qt.DisplayRole, testresult.message) testcase_item.setData(3, Qt.DisplayRole, testresult.time * 1e3) color = COLORS[testresult.category] for col in range(self.columnCount()): testcase_item.setBackground(col, color) if testresult.extra_text: for line in testresult.extra_text.rstrip().split("\n"): error_content_item = QTreeWidgetItem(testcase_item) error_content_item.setData(0, Qt.DisplayRole, line) error_content_item.setFirstColumnSpanned(True) error_content_item.setFont(0, monospace_font) counts = Counter(res.category for res in self.testresults) if counts[Category.FAIL] == 1: test_or_tests = _('test') else: test_or_tests = _('tests') failed_txt = '{} {} failed'.format(counts[Category.FAIL], test_or_tests) passed_txt = '{} passed'.format(counts[Category.OK]) other_txt = '{} other'.format(counts[Category.SKIP]) msg = '<b>{}, {}, {}</b>'.format(failed_txt, passed_txt, other_txt) return msg
def __init__(self, parent=None, standalone=False): super(GcodeLexer, self).__init__(parent) # This prevents doing unneeded initialization # when QtDesginer loads the plugin. if parent is None and not standalone: return self._styles = { 0: 'Default', 1: 'Comment', 2: 'Key', 3: 'Assignment', 4: 'Value', } for key, value in self._styles.iteritems(): setattr(self, value, key) font = QFont() font.setFamily('Courier') font.setFixedPitch(True) font.setPointSize(10) font.setBold(True) self.setFont(font, 2)
def set_font_size(self, font_size): """ Updates the font size of the objects Parameters ---------- font_size : int the font size """ if self.font_size == font_size: return self.font_size = font_size font = QFont() font.setPointSize(font_size) self.setFont(font) self.name_edit.setFont(font) self.min_edit.setFont(font) self.max_edit.setFont(font) self.format_edit.setFont(font) self.scale_edit.setFont(font) self.phase_edit.setFont(font) self.nlabels_edit.setFont(font) self.labelsize_edit.setFont(font) self.ncolors_edit.setFont(font)
def __init__(self, *args, **kwargs): """Frame used in css styling with fade in and fade out effect.""" super(FrameContentHover, self).__init__(*args, **kwargs) self.current_opacity = 0 self.max_frame = 100 self.max_opacity = 0.95 self.button_text = None self.label_icon = None self.label_text = None self.summary = '' # Widgets self.text_document = QTextDocument(self) self.timeline = QTimeLine(500) font = QFont() if sys.platform == 'darwin': font.setPointSize(12) elif os.name == 'nt': font.setPointSize(9) else: font.setPointSize(9) self.text_document.setDefaultFont(font) self.text_document.setMaximumBlockCount(5) self.text_document.setDocumentMargin(10) # Setup self.setWindowFlags(Qt.FramelessWindowHint) self.setAutoFillBackground(True) self.setWindowFlags(Qt.FramelessWindowHint) self.setMinimumSize(self.widget_size()) self.timeline.setFrameRange(0, self.max_frame) # Signals self.timeline.frameChanged.connect(self.set_opacity)
def __init__(self, hub, *args, **kwargs): super().__init__(*args, **kwargs) self.hub = hub self.wave_range = (None, None) loadUi(os.path.join(os.path.dirname(__file__), "ui", "linelists_window.ui"), self) # QtDesigner can't add a combo box to a tool bar... self.line_list_selector = QComboBox() self.line_list_selector.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.line_list_selector.setMinimumWidth(230) self.line_list_selector.setToolTip("Select line list from internal library") self.main_toolbar.addWidget(self.line_list_selector) # QtDesigner creates tabbed widgets with 2 tabs, and doesn't allow # removing then in the designer itself. Remove in here then. while self.tab_widget.count() > 0: self.tab_widget.removeTab(0) # Local references for often used objects. self.plot_window = self.hub.plot_window # Request that line lists be read from wherever are they sources. if not hasattr(self, 'linelists'): self._request_linelists() # Populate line list selector with internal line lists model = self.line_list_selector.model() item = QStandardItem("Select line list") font = QFont("Monospace") font.setStyleHint(QFont.TypeWriter) font.setPointSize(12) item.setFont(font) model.appendRow(item) for description in linelist.descriptions(): item = QStandardItem(str(description)) item.setFont(font) model.appendRow(item) self.line_labels_plotter = LineLabelsPlotter(self) # Connect controls to appropriate signals. self.draw_button.clicked.connect( lambda:self.line_labels_plotter._plot_linelists( table_views=self._get_table_views(), panes=self._get_panes(), units=self.hub.plot_widget.spectral_axis_unit, caller=self.line_labels_plotter)) self.erase_button.clicked.connect(lambda:self.erase_linelabels.emit(self.plot_window.plot_widget)) self.dismiss_button.clicked.connect(self.dismiss_linelists_window.emit) self.actionOpen.triggered.connect(lambda:self._open_linelist_file(file_name=None)) self.actionExport.triggered.connect(lambda:self._export_to_file(file_name=None)) self.line_list_selector.currentIndexChanged.connect(self._lineList_selection_change) self.tab_widget.tabCloseRequested.connect(self._on_tab_close) self.hub.plot_window.window_removed.connect(self.dismiss_linelists_window.emit)
def __init__(self, plot_window, parent=None): super(LineListsWindow, self).__init__() self.plot_window = plot_window # Builds GUI self._main_window = ClosableMainWindow() self.setupUi(self._main_window, str(plot_window)) self.tabWidget.tabCloseRequested.connect(self.tab_close) # Request that line lists be read from wherever are they sources. dispatch.on_request_linelists.emit() # Populate line list selector with internal line lists model = self.line_list_selector.model() item = QStandardItem("Select line list") font = QFont("Monospace") font.setStyleHint(QFont.TypeWriter) font.setPointSize(12) item.setFont(font) model.appendRow(item) for description in linelist.descriptions(): item = QStandardItem(str(description)) item.setFont(font) model.appendRow(item) #------------ UNCOMMENT TO LOAD LISTS AUTOMATICALLY -------------- # # Populate GUI. # # This is commented out for now to comply with the decision about # not showing any line list automatically upon startup. In case # we need that capability back, just uncomment this line. # self._buildViews(plot_window) #--------------------------------------------------------------- # Connect controls to appropriate signals. # # Note that, for the Draw operation, we have to pass the table views to # the handler, even though it would be better to handle the row selections # all in here for the sake of encapsulation. This is so because this class # is not a QWidget or one of its subclasses, thus it cannot implement a # DispatchHandle signal handler. self.draw_button.clicked.connect( lambda: dispatch.on_plot_linelists.emit( table_views=self._getTableViews(), panes=self._getPanes(), units=plot_window.waverange[0].unit, caller=plot_window)) self.erase_button.clicked.connect( lambda: dispatch.on_erase_linelabels.emit(caller=plot_window)) self.dismiss_button.clicked.connect( lambda: dispatch.on_dismiss_linelists_window.emit(close=False)) self.actionOpen.triggered.connect( lambda: self._open_linelist_file(file_name=None)) self.actionExport.triggered.connect( lambda: self._export_to_file(file_name=None)) self.line_list_selector.currentIndexChanged.connect( self._lineList_selection_change)
def __init__(self, parent=None): QDialog.__init__(self, parent=parent) self._shortcuts_summary_title = SHORTCUTS_SUMMARY_TITLE # Calculate font and amount of elements in each column # according screen size width, height = self.get_screen_resolution() font_size = height / 80 font_size = max(min(font_size, MAX_FONT_SIZE), MIN_FONT_SIZE) shortcuts_column = (height - 8 * font_size) / (font_size + 16) # Widgets style = """ QDialog { margin:0px; padding:0px; border-radius: 2px; }""" self.setStyleSheet(style) font_names = QFont() font_names.setPointSize(font_size) font_names.setBold(True) font_keystr = QFont() font_keystr.setPointSize(font_size) font_title = QFont() font_title.setPointSize(font_size + 2) font_title.setBold(True) title_label = QLabel(self._shortcuts_summary_title) title_label.setAlignment(Qt.AlignCenter) title_label.setFont(font_title) # iter over shortcuts and create GroupBox for each context # with shortcuts in a grid columns_layout = QHBoxLayout() added_shortcuts = 0 group = None # group shortcuts by context shortcuts = groupby(sorted(CONF.iter_shortcuts()), key=itemgetter(0)) for __, group_shortcuts in shortcuts: for i, (context, name, keystr) in enumerate(group_shortcuts): # start of every column if added_shortcuts == 0: column_layout = QVBoxLayout() # at start of new context add previous context group if i == 0 and added_shortcuts > 0: column_layout.addWidget(group) # create group at start of column or context if added_shortcuts == 0 or i == 0: if context == '_': context = 'Global' group = QGroupBox(context.capitalize()) group.setFont(font_names) group_layout = QGridLayout() group.setLayout(group_layout) # Count space for titles added_shortcuts += 1 # Widgets label_name = QLabel(name.capitalize().replace('_', ' ')) label_name.setFont(font_names) keystr = QKeySequence(keystr).toString(QKeySequence.NativeText) label_keystr = QLabel(keystr) label_keystr.setFont(font_keystr) group_layout.addWidget(label_name, i, 0) group_layout.addWidget(label_keystr, i, 1) added_shortcuts += 1 if added_shortcuts >= shortcuts_column: column_layout.addWidget(group) columns_layout.addLayout(column_layout) added_shortcuts = 0 column_layout.addWidget(group) column_layout.addStretch() # avoid lasts sections to appear too big columns_layout.addLayout(column_layout) # Scroll widget self.scroll_widget = QWidget() self.scroll_widget.setLayout(columns_layout) self.scroll_area = QScrollArea() self.scroll_area.setWidget(self.scroll_widget) # widget setup self.setWindowFlags(Qt.FramelessWindowHint) self.setWindowOpacity(0.95) # layout self._layout = QVBoxLayout() self._layout.addWidget(title_label) self._layout.addWidget(self.scroll_area) self.setLayout(self._layout) self.setGeometry(0, 0, width, height)
def populate_tree(self): """Create each item (and associated data) in the tree""" if not self.stats: warn_item = QTreeWidgetItem(self) warn_item.setData( 0, Qt.DisplayRole, _('No timings to display. ' 'Did you forget to add @profile decorators ?') .format(url=WEBSITE_URL)) warn_item.setFirstColumnSpanned(True) warn_item.setTextAlignment(0, Qt.AlignCenter) font = warn_item.font(0) font.setStyle(QFont.StyleItalic) warn_item.setFont(0, font) return try: monospace_font = self.window().editor.get_plugin_font() except AttributeError: # If run standalone for testing monospace_font = QFont("Courier New") monospace_font.setPointSize(10) for func_info, func_data in self.stats.items(): # Function name and position filename, start_line_no, func_name = func_info func_stats, func_total_time = func_data func_item = QTreeWidgetItem(self) func_item.setData( 0, Qt.DisplayRole, _('{func_name} ({time_ms:.3f}ms) in file "{filename}", ' 'line {line_no}').format( filename=filename, line_no=start_line_no, func_name=func_name, time_ms=func_total_time * 1e3)) func_item.setFirstColumnSpanned(True) func_item.setData(COL_POS, Qt.UserRole, (osp.normpath(filename), start_line_no)) # For sorting by time func_item.setData(COL_TIME, Qt.DisplayRole, func_total_time * 1e3) func_item.setData(COL_PERCENT, Qt.DisplayRole, func_total_time * 1e3) if self.parent().use_colors: # Choose deteministic unique color for the function md5 = hashlib.md5((filename + func_name).encode("utf8")).hexdigest() hue = (int(md5[:2], 16) - 68) % 360 # avoid blue (unreadable) func_color = QColor.fromHsv(hue, 200, 255) else: # Red color only func_color = QColor.fromRgb(255, 0, 0) # Lines of code for line_info in func_stats: line_item = QTreeWidgetItem(func_item) (line_no, code_line, line_total_time, time_per_hit, hits, percent) = line_info self.fill_item( line_item, filename, line_no, code_line, line_total_time, percent, time_per_hit, hits) # Color background if line_total_time is not None: alpha = percent color = QColor(func_color) color.setAlphaF(alpha) # Returns None color = QBrush(color) for col in range(self.columnCount()): line_item.setBackground(col, color) else: for col in range(self.columnCount()): line_item.setForeground(col, CODE_NOT_RUN_COLOR) # Monospace font for code line_item.setFont(COL_LINE, monospace_font)
def __init__(self, parent=None): QDialog.__init__(self, parent=parent) self._shortcuts_summary_title = _("Spyder Keyboard ShortCuts") # Calculate font and amount of elements in each column according screen size width, height = self.get_screen_resolution() font_size = height / 80 font_size = max(min(font_size, MAX_FONT_SIZE), MIN_FONT_SIZE) shortcuts_column = (height - 8 * font_size) / (font_size +16) # Widgets style = """ QDialog { margin:0px; padding:0px; border-radius: 2px; }""" self.setStyleSheet(style) font_names = QFont() font_names.setPointSize(font_size) font_names.setBold(True) font_keystr = QFont() font_keystr.setPointSize(font_size) font_title = QFont() font_title.setPointSize(font_size+2) font_title.setBold(True) title_label = QLabel(self._shortcuts_summary_title) title_label.setAlignment(Qt.AlignCenter) title_label.setFont(font_title) # iter over shortcuts and create GroupBox for each context # with shortcuts in a grid columns_layout = QHBoxLayout() added_shortcuts = 0 group = None # group shortcuts by context shortcuts = groupby(sorted(iter_shortcuts()), key=itemgetter(0)) for context, group_shortcuts in shortcuts: for i, (context, name, keystr) in enumerate(group_shortcuts): # start of every column if added_shortcuts == 0: column_layout = QVBoxLayout() # at start of new context add previous context group if i == 0 and added_shortcuts > 0: column_layout.addWidget(group) # create group at start of column or context if added_shortcuts == 0 or i == 0: if context == '_': context = 'Global' group = QGroupBox(context.capitalize()) group.setFont(font_names) group_layout = QGridLayout() group.setLayout(group_layout) # Count space for titles added_shortcuts += 1 # Widgets label_name = QLabel(name.capitalize().replace('_', ' ')) label_name.setFont(font_names) keystr = QKeySequence(keystr).toString(QKeySequence.NativeText) label_keystr = QLabel(keystr) label_keystr.setFont(font_keystr) group_layout.addWidget(label_name, i, 0) group_layout.addWidget(label_keystr, i, 1) added_shortcuts += 1 if added_shortcuts >= shortcuts_column: column_layout.addWidget(group) columns_layout.addLayout(column_layout) added_shortcuts = 0 column_layout.addWidget(group) column_layout.addStretch() # avoid lasts sections to appear too big columns_layout.addLayout(column_layout) # Scroll widget self.scroll_widget = QWidget() self.scroll_widget.setLayout(columns_layout) self.scroll_area = QScrollArea() self.scroll_area.setWidget(self.scroll_widget) # widget setup self.setWindowFlags(Qt.FramelessWindowHint) self.setWindowOpacity(0.95) # layout self._layout = QVBoxLayout() self._layout.addWidget(title_label) self._layout.addWidget(self.scroll_area) self.setLayout(self._layout) self.setGeometry(0, 0, width, height)
def initialize_editor(self): self.editor = QsciScintilla() # self.editor.cursorPositionChanged.connect(self.e) # self.editor.copyAvailable.connect(self.e) # self.editor.indicatorClicked.connect(self.e) # self.editor.indicatorReleased.connect(self.e) # self.editor.linesChanged.connect(self.e) # self.editor.marginClicked.connect(self.e) # self.editor.modificationAttempted.connect(self.e) # self.editor.modificationChanged.connect(self.e) # self.editor.selectionChanged.connect(self.e) # self.editor.textChanged.connect(self.e) # self.editor.userListActivated.connect(self.e) if self.editor.__class__.__name__ == "LineTextWidget": return # When using PySide without QSciScintilla # define the font to use font = QFont() font.setFamily("Consolas") font.setFixedPitch(True) font.setPointSize(10) # the font metrics here will help # building the margin width later fm = QFontMetrics(font) # set the default font of the self.editor # and take the same font for line numbers self.editor.setFont(font) self.editor.setMarginsFont(font) # Line numbers # conventionnaly, margin 0 is for line numbers self.editor.setMarginWidth(0, fm.width("00000") + 5) self.editor.setMarginLineNumbers(0, True) self.editor.setTabWidth(4) # Folding visual : we will use boxes self.editor.setFolding(QsciScintilla.BoxedTreeFoldStyle) self.editor.setAutoIndent(True) # Braces matching self.editor.setBraceMatching(QsciScintilla.SloppyBraceMatch) # Editing line color self.editor.setCaretLineVisible(True) self.editor.setCaretLineBackgroundColor(QColor("#CDA869")) # Margins colors # line numbers margin self.editor.setMarginsBackgroundColor(QColor("#333333")) self.editor.setMarginsForegroundColor(QColor("#CCCCCC")) # folding margin colors (foreground,background) self.editor.setFoldMarginColors(QColor("#99CC66"), QColor("#333300")) # Choose a lexer self.lexer = QsciLexerPython() self.lexer.setDefaultFont(font) # Set the length of the string before the editor tries to autocomplete # In practise this would be higher than 1 # But its set lower here to make the autocompletion more obvious self.editor.setAutoCompletionThreshold(1) # Tell the editor we are using a QsciAPI for the autocompletion self.editor.setAutoCompletionSource(QsciScintilla.AcsAPIs) self.editor.setLexer(self.lexer) self.editor.setCallTipsStyle(QsciScintilla.CallTipsContext) # self.editor.setCallTipsVisible(0) # Create an API for us to populate with our autocomplete terms self.api = QsciAPIs(self.lexer) # Compile the api for use in the lexer self.api.prepare()
class TestDataModel(QAbstractItemModel): """ Model class storing test results for display. Test results are stored as a list of TestResults in the property `self.testresults`. Every test is exposed as a child of the root node, with extra information as second-level nodes. As in every model, an iteem of data is identified by its index, which is a tuple (row, column, id). The id is TOPLEVEL_ID for top-level items. For level-2 items, the id is the index of the test in `self.testresults`. Signals ------- sig_summary(str) Emitted with new summary if test results change. """ sig_summary = Signal(str) def __init__(self, parent=None): """Constructor.""" QAbstractItemModel.__init__(self, parent) self.abbreviator = Abbreviator() self.testresults = [] try: self.monospace_font = parent.window().editor.get_plugin_font() except AttributeError: # If run standalone for testing self.monospace_font = QFont("Courier New") self.monospace_font.setPointSize(10) @property def testresults(self): """List of test results.""" return self._testresults @testresults.setter def testresults(self, new_value): """Setter for test results.""" self.beginResetModel() self.abbreviator = Abbreviator(res.name for res in new_value) self._testresults = new_value self.endResetModel() self.emit_summary() def add_testresults(self, new_tests): """ Add new test results to the model. Arguments --------- new_tests : list of TestResult """ firstRow = len(self.testresults) lastRow = firstRow + len(new_tests) - 1 for test in new_tests: self.abbreviator.add(test.name) self.beginInsertRows(QModelIndex(), firstRow, lastRow) self.testresults.extend(new_tests) self.endInsertRows() self.emit_summary() def update_testresults(self, new_results): """ Update some test results by new results. The tests in `new_results` should already be included in `self.testresults` (otherwise a `KeyError` is raised). This function replaces the existing results by `new_results`. Arguments --------- new_results: list of TestResult """ idx_min = idx_max = None for new_result in new_results: for (idx, old_result) in enumerate(self.testresults): if old_result.name == new_result.name: self.testresults[idx] = new_result if idx_min is None: idx_min = idx_max = idx else: idx_min = min(idx_min, idx) idx_max = max(idx_max, idx) break else: raise KeyError('test not found') if idx_min is not None: self.dataChanged.emit(self.index(idx_min, 0), self.index(idx_max, len(HEADERS) - 1)) self.emit_summary() def index(self, row, column, parent=QModelIndex()): """ Construct index to given item of data. If `parent` not valid, then the item of data is on the top level. """ if not self.hasIndex(row, column, parent): # check bounds etc. return QModelIndex() if not parent.isValid(): return self.createIndex(row, column, TOPLEVEL_ID) else: testresult_index = parent.row() return self.createIndex(row, column, testresult_index) def data(self, index, role): """ Return data in `role` for item of data that `index` points to. If `role` is `DisplayRole`, then return string to display. If `role` is `TooltipRole`, then return string for tool tip. If `role` is `FontRole`, then return monospace font for level-2 items. If `role` is `BackgroundRole`, then return background color. If `role` is `TextAlignmentRole`, then return right-aligned for time. If `role` is `UserRole`, then return location of test as (file, line). """ if not index.isValid(): return None row = index.row() column = index.column() id = index.internalId() if role == Qt.DisplayRole: if id != TOPLEVEL_ID: return self.testresults[id].extra_text[index.row()] elif column == STATUS_COLUMN: return self.testresults[row].status elif column == NAME_COLUMN: return self.abbreviator.abbreviate(self.testresults[row].name) elif column == MESSAGE_COLUMN: return self.testresults[row].message elif column == TIME_COLUMN: time = self.testresults[row].time return '' if time is None else '{:.2f}'.format(time * 1e3) elif role == Qt.ToolTipRole: if id == TOPLEVEL_ID and column == NAME_COLUMN: return self.testresults[row].name elif role == Qt.FontRole: if id != TOPLEVEL_ID: return self.monospace_font elif role == Qt.BackgroundRole: if id == TOPLEVEL_ID: testresult = self.testresults[row] return COLORS[testresult.category] elif role == Qt.TextAlignmentRole: if id == TOPLEVEL_ID and column == TIME_COLUMN: return Qt.AlignRight elif role == Qt.UserRole: if id == TOPLEVEL_ID: testresult = self.testresults[row] return (testresult.filename, testresult.lineno) else: return None def headerData(self, section, orientation, role=Qt.DisplayRole): """Return data for specified header.""" if orientation == Qt.Horizontal and role == Qt.DisplayRole: return HEADERS[section] else: return None def parent(self, index): """Return index to parent of item that `index` points to.""" if not index.isValid(): return QModelIndex() id = index.internalId() if id == TOPLEVEL_ID: return QModelIndex() else: return self.index(id, 0) def rowCount(self, parent=QModelIndex()): """Return number of rows underneath `parent`.""" if not parent.isValid(): return len(self.testresults) if parent.internalId() == TOPLEVEL_ID and parent.column() == 0: return len(self.testresults[parent.row()].extra_text) return 0 def columnCount(self, parent=QModelIndex()): """Return number of rcolumns underneath `parent`.""" if not parent.isValid(): return len(HEADERS) else: return 1 def sort(self, column, order): """Sort model by `column` in `order`.""" def key_time(result): return result.time or -1 self.beginResetModel() reverse = order == Qt.DescendingOrder if column == STATUS_COLUMN: self.testresults.sort(key=attrgetter('category', 'status'), reverse=reverse) elif column == NAME_COLUMN: self.testresults.sort(key=attrgetter('name'), reverse=reverse) elif column == MESSAGE_COLUMN: self.testresults.sort(key=attrgetter('message'), reverse=reverse) elif column == TIME_COLUMN: self.testresults.sort(key=key_time, reverse=reverse) self.endResetModel() def summary(self): """Return summary for current results.""" def n_test_or_tests(n): test_or_tests = _('test') if n == 1 else _('tests') return '{} {}'.format(n, test_or_tests) if not len(self.testresults): return _('No results to show.') counts = Counter(res.category for res in self.testresults) if all(counts[cat] == 0 for cat in (Category.FAIL, Category.OK, Category.SKIP)): txt = n_test_or_tests(counts[Category.PENDING]) return _('collected {}').format(txt) msg = _('{} failed').format(n_test_or_tests(counts[Category.FAIL])) msg += _(', {} passed').format(counts[Category.OK]) if counts[Category.SKIP]: msg += _(', {} other').format(counts[Category.SKIP]) if counts[Category.PENDING]: msg += _(', {} pending').format(counts[Category.PENDING]) return msg def emit_summary(self): """Emit sig_summary with summary for current results.""" self.sig_summary.emit(self.summary())