def show_mouse_toast(message): # Creates a text with empty space to get the height of the rendered text - this is used # to provide the same offset for the tooltip, scaled relative to the current resolution and zoom. font_metrics = QFontMetrics(QFont(" ")) # The height itself is divided by 2 just to reduce the offset so that the tooltip is # reasonably position relative to the cursor QToolTip.showText(QCursor.pos() + QPoint(font_metrics.height() / 2, 0), message)
def setZoom(self, zoom): '''Set a new zoom level. Args: zoom (int): The new zoom level. ''' self._zoom = zoom zoomSelector = clip(zoom, self._minZoomScale, self._maxZoomScale) meters = self._scaleView[zoomSelector] if meters >= 1000: self._text = '%d km' % (meters / 1000.0) else: self._text = '%d m' % meters self._meters = meters self._meterPerPixelsEquator = self.EarthCircumference / np.power(2.0, zoom + 8) # Evaluate the bounding box of the current text anchor = self._anchor textRect = QFontMetrics(QFont()).boundingRect(self._text) if anchor == Qt.BottomRightCorner or anchor == Qt.TopRightCorner: textRect.moveLeft(-textRect.width() - 10) textRect.moveTop(-textRect.height() + 10) else: textRect.moveTop(-textRect.height() + 14) self._textRect = QRectF(textRect) self.update()
def draw_model_name(painter: QPainter, geom: NodeGeometry, state: NodeState, model: NodeDataModel, node_style: NodeStyle): """ Draw model name Parameters ---------- painter : QPainter geom : NodeGeometry state : NodeState model : NodeDataModel """ if not model.caption_visible: return name = model.caption f = painter.font() f.setBold(True) metrics = QFontMetrics(f) rect = metrics.boundingRect(name) position = QPointF((geom.width - rect.width()) / 2.0, (geom.spacing + geom.entry_height) / 3.0) painter.setFont(f) painter.setPen(node_style.font_color) painter.drawText(position, name) f.setBold(False) painter.setFont(f)
def resizeEvent(self, event: QResizeEvent): metric = QFontMetrics(self.file_view.font()) width = self.file_view.width() - 45 for i, text in enumerate(self.file_list): clipped_text = metric.elidedText(text, Qt.ElideLeft, width) item: QTreeWidgetItem = self.file_view.topLevelItem(i) item.setText(0, clipped_text)
def _setup_editor(self, default_content, filename): editor = self.editor # use tabs not spaces for indentation editor.setIndentationsUseTabs(False) editor.setTabWidth(TAB_WIDTH) # show current editing line but in a softer color editor.setCaretLineBackgroundColor(CURRENTLINE_BKGD_COLOR) editor.setCaretLineVisible(True) # set a margin large enough for sensible file sizes < 1000 lines # and the progress marker font_metrics = QFontMetrics(self.font()) editor.setMarginWidth(1, font_metrics.averageCharWidth() * 3 + 20) # fill with content if supplied and set source filename if default_content is not None: editor.setText(default_content) if filename is not None: editor.setFileName(filename) # Default content does not count as a modification editor.setModified(False) editor.enableAutoCompletion(CodeEditor.AcsAll)
def update_font(self): self.setFont(self.textEditor.font()) self.fontmetric = QFontMetrics(self.textEditor.font()) self.prefixwidth = self.fontmetric.width('12345') self.prefixheight = self.fontmetric.height() self.setFixedWidth(self.prefixwidth) self.textEditor.setViewportMargins(self.prefixwidth, 0, 0, 0)
def draw_validation_rect(painter: QPainter, geom: NodeGeometry, model: NodeDataModel, graphics_object: NodeGraphicsObject, node_style: NodeStyle): """ Draw validation rect Parameters ---------- painter : QPainter geom : NodeGeometry model : NodeDataModel graphics_object : NodeGraphicsObject node_style : NodeStyle """ model_validation_state = model.validation_state() if model_validation_state == NodeValidationState.valid: return color = (node_style.selected_boundary_color if graphics_object.isSelected() else node_style.normal_boundary_color) if geom.hovered: p = QPen(color, node_style.hovered_pen_width) else: p = QPen(color, node_style.pen_width) painter.setPen(p) # Drawing the validation message background if model_validation_state == NodeValidationState.error: painter.setBrush(node_style.error_color) else: painter.setBrush(node_style.warning_color) radius = 3.0 diam = node_style.connection_point_diameter boundary = QRectF( -diam, -diam + geom.height - geom.validation_height, 2.0 * diam + geom.width, 2.0 * diam + geom.validation_height, ) painter.drawRoundedRect(boundary, radius, radius) painter.setBrush(Qt.gray) # Drawing the validation message itself error_msg = model.validation_message() f = painter.font() metrics = QFontMetrics(f) rect = metrics.boundingRect(error_msg) position = QPointF( (geom.width - rect.width()) / 2.0, geom.height - (geom.validation_height - diam) / 2.0 ) painter.setFont(f) painter.setPen(node_style.font_color) painter.drawText(position, error_msg)
def __init__(self, info_text: str = "", parent: typing.Optional[QWidget] = None): super().__init__(info_text if info_text else "-", parent) self.hide_list = [] self.stateChanged.connect(self.hide_element) metrics = QFontMetrics(QFont()) self.text_size = metrics.size(Qt.TextSingleLine, info_text) self.info_text = info_text
def sizeHint(self): font_metrics = QFontMetrics(self.font()) r = font_metrics.boundingRect( QRect(QPoint(0, 0), self.size()), Qt.TextWordWrap | Qt.ElideRight, self._text, ) return QSize(self.width(), r.height())
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) text = self.text() font = self.font() fm = QFontMetrics(font) text_width = fm.width(text) + 6 self.setFixedWidth(text_width)
def sizeHint(self): """Override Qt method. Returns the widget size hint (based on the editor font size). """ fm = QFontMetrics(self.editor.font()) size_hint = QSize(fm.height(), fm.height()) if size_hint.width() > 16: size_hint.setWidth(16) return size_hint
def __init__(self, parent, widthSpace=10): super().__init__() self.parent = parent self.widthSpace = widthSpace self.dateFmt = "%d %b %Y" self.headerLabels = [ 'Date', 'Time', 'Distance (km)', 'Avg. speed\n(km/h)', 'Calories', 'Gear' ] self.setHeaderLabels(self.headerLabels) self.header().setStretchLastSection(False) # make header tall enough for two rows of text (avg speed has line break) font = self.header().font() metrics = QFontMetrics(font) height = metrics.height() self.header().setMinimumHeight(height * 2) # align header text centrally for idx in range(len(self.headerLabels)): self.headerItem().setTextAlignment(idx, Qt.AlignCenter) self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.makeTree() self.sortColumn = None self.sortDescending = [True for _ in range(len(self.headerLabels))] self.header().setSectionsClickable(True) self.header().sectionClicked.connect(self.sortTree) self.currentItemChanged.connect(self._itemChanged) self.itemSelectionChanged.connect(self._summariseSelected) self.sortTree(0) msg = "Browse all sessions, grouped by month. Click on the headers \n" msg += "to sort by that metric in ascending or descending order.\n" msg += "Click on a session to highlight it in the plot." self.setToolTip(msg) self.editAction = QAction("Edit") self.editAction.setShortcut(QKeySequence("Ctrl+E")) self.editAction.triggered.connect(self._editItems) self.addAction(self.editAction) self.mergeAction = QAction("Merge") self.mergeAction.setShortcut(QKeySequence("Ctrl+M")) self.mergeAction.triggered.connect(self.combineRows) self.addAction(self.mergeAction) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self._showContextMenu)
def updateText(self): self.checkItems = [] for i in range(self.model().rowCount()): if self.model().item(i).checkState() == Qt.Checked: self.checkItems.append(self.model().item(i).text()) text = ", ".join(self.checkItems) # Compute elided text (with "...") metrics = QFontMetrics(self.lineEdit().font()) elidedText = metrics.elidedText(text, Qt.ElideRight, self.lineEdit().width()) self.lineEdit().setText(elidedText)
def resize_to_content(self, lines): if len(lines) == 0: lines.append('') # resize properly fm = QFontMetrics(self.font()) text_width = fm.width(lines[0]+'__') text_width = text_width+20 # some buffer text_height = fm.height()*(len(lines))+12 # also some vertical buffer self.setFixedWidth(text_width if text_width > self.base_width else self.base_width) self.setFixedHeight(text_height if text_height > self.base_height else self.base_height) self.parent_node_instance.update_shape()
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 __init__( self, title, data_sequence, unit: Units, parent=None, input_type=QDoubleSpinBox, decimals=2, data_range=(0, 100000), single_step=1, ): """ :type data_sequence: list[(float)] :param data_sequence: :type input_type: () -> (QDoubleSpinBox | QSpinBox) :param parent: :type decimals: int|None :type data_range: (float, float) :type single_step: float :type title: str """ super().__init__(parent) layout = QHBoxLayout() layout.addWidget(QLabel("<strong>{}</strong>".format(title))) self.elements = [] if len(data_sequence) == 2: data_sequence = (1, ) + tuple(data_sequence) for name, value in zip(["z", "y", "x"], data_sequence): lab = QLabel(name + ":") layout.addWidget(lab) val = input_type() val.setButtonSymbols(QAbstractSpinBox.NoButtons) if isinstance(val, QDoubleSpinBox): val.setDecimals(decimals) val.setRange(*data_range) val.setValue(value * UNIT_SCALE[unit.value]) val.setAlignment(Qt.AlignRight) val.setSingleStep(single_step) font = val.font() fm = QFontMetrics(font) val_len = max(fm.width(str(data_range[0])), fm.width(str(data_range[1]))) + fm.width(" " * 8) val.setFixedWidth(val_len) layout.addWidget(val) self.elements.append(val) self.units = EnumComboBox(Units) self.units.set_value(unit) layout.addWidget(self.units) self.has_units = True layout.addStretch(1) self.setLayout(layout)
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
def get_text_width(text) -> int: """Return the width required to render ``text`` (including rich text elements).""" if qtpy.PYSIDE2: from qtpy.QtGui import Qt as _Qt else: from qtpy.QtCore import Qt as _Qt if _Qt.mightBeRichText(text): doc = QTextDocument() doc.setHtml(text) return doc.size().width() else: fm = QFontMetrics(QFont("", 0)) return fm.boundingRect(text).width() + 5
def sizeHint(self): self.ensurePolished() fm = QFontMetrics(self.font()) h = self.lineEdit().sizeHint().height() if hasattr(fm, 'horizontalAdvance'): # Qt >= 5.11 w = fm.horizontalAdvance(str(self._value)) + 3 else: w = fm.width(str(self._value)) + 3 w = max(36, w) opt = QStyleOptionSpinBox() self.initStyleOption(opt) hint = QSize(w, h) return self.style().sizeFromContents(QStyle.CT_SpinBox, opt, hint, self)
def resize_to_content(self, lines): if len(lines) == 0: lines.append('') # resize properly fm = QFontMetrics(self.font()) text_width = fm.width(lines[0] + ('_' * 2)) text_width = text_width + 20 # some buffer text_height = fm.height() * ( len(lines)) + 15 # vertical buffer for padding etc. self.setFixedWidth( text_width if text_width > self.base_width else self.base_width) self.setFixedHeight(text_height if text_height > self.base_height else self.base_height) self.node.update_shape()
def _resize_axis_labels(self): """When any of the labels get updated, this method updates all label widths to the width of the longest label. This keeps the sliders left-aligned and allows the full label to be visible at all times, with minimal space, without setting stretch on the layout. """ fm = QFontMetrics(QFont("", 0)) labels = self.findChildren(QLineEdit, 'axis_label') newwidth = max([fm.boundingRect(lab.text()).width() for lab in labels]) if any(self._displayed_sliders): # set maximum width to no more than 20% of slider width maxwidth = self.slider_widgets[0].width() * 0.2 newwidth = min([newwidth, maxwidth]) for labl in labels: labl.setFixedWidth(newwidth + 10)
def fontmetrics(self, font): fid = font.toString() fm = self._fm_cache.get(fid) if fm is None: return self._fm_cache.setdefault(fid, QFontMetrics(font)) else: return fm
def __init__(self, value='', parent=None, get_pos=None): super().__init__(value, parent=parent) self.fm = QFontMetrics(QFont("", 0)) self.setObjectName('slice_label') self.min_width = 30 self.max_width = 200 self.setCursor(Qt.IBeamCursor) self.setValidator(QDoubleValidator()) self.textChanged.connect(self._on_text_changed) self._on_text_changed(value) self.get_pos = get_pos if parent is not None: self.min_width = 50 self.slider = parent.slider self.setAlignment(Qt.AlignCenter)
def save_state_action(self, state: ProjectInfoBase, custom_name): # TODO left elipsis # state: ProjectInfoBase = self.get_state() if not isinstance(state, ProjectInfoBase): # workaround for PointsInfo load return normed_file_path = os.path.normpath(state.file_path) sub_dict = self.state_dict[normed_file_path] name = f"state {self.state_dict_count[normed_file_path]+1}" if custom_name: name, ok = QInputDialog.getText(self, "Save name", "Save name:", text=name) if not ok: return while name in sub_dict or name in ["raw image", "image with mask"]: name, ok = QInputDialog.getText(self, "Save name", "Save name (previous in use):", text=name) if not ok: return try: index = self.file_list.index(os.path.normpath(normed_file_path)) item = self.file_view.topLevelItem(index) except ValueError: metric = QFontMetrics(self.file_view.font()) width = self.file_view.width() - 45 clipped_text = metric.elidedText(normed_file_path, Qt.ElideLeft, width) item = QTreeWidgetItem(self.file_view, [clipped_text]) item.setToolTip(0, normed_file_path) self.file_list.append(normed_file_path) QTreeWidgetItem(item, ["raw image"]) sub_dict["raw image"] = state.get_raw_copy() if state.is_masked(): QTreeWidgetItem(item, ["image with mask"]) sub_dict["image with mask"] = state.get_raw_mask_copy() item.setExpanded(True) if state.is_raw(): return it = QTreeWidgetItem(item, [name]) self.file_view.setCurrentItem(it) sub_dict[name] = state self.state_dict_count[state.file_path] += 1
def defaultIndent(self): if self.frameWidth() <= 0: return 0 if self.__data.text.testPaintAttribute(QwtText.PaintUsingTextFont): fnt = self.__data.text.font() else: fnt = self.font() return QFontMetrics(fnt).width("x") / 2
def set_tab_size(self, length=4): """ 设置tab占位长度 Set tab length. """ self.master.setTabStopDistance(length * QFontMetrics(self.font).width(" "))
class ElidingLabel(QLabel): """A single-line eliding QLabel.""" def __init__(self, text='', parent=None): super().__init__(parent) self._text = text self.fm = QFontMetrics(self.font()) def setText(self, txt): self._text = txt short = self.fm.elidedText(self._text, Qt.ElideRight, self.width()) super().setText(short) def resizeEvent(self, rEvent): width = rEvent.size().width() short = self.fm.elidedText(self._text, Qt.ElideRight, width) super().setText(short) rEvent.accept()
def _resize_slice_labels(self): """When the size of any dimension changes, we want to resize all of the slice labels to width of the longest label, to keep all the sliders right aligned. The width is determined by the number of digits in the largest dimensions, plus a little padding. """ width = 0 for ax, maxi in enumerate(self.dims.max_indices): if self._displayed_sliders[ax]: length = len(str(int(maxi))) if length > width: width = length # gui width of a string of length `width` fm = QFontMetrics(QFont("", 0)) width = fm.boundingRect("8" * width).width() for labl in self.findChildren(QWidget, 'slice_label'): labl.setFixedWidth(width + 6)
def __init__(self, colormap: BaseColormap, accepted: bool, name: str, removable: bool = False, used: bool = False): super().__init__() self.image = convert_colormap_to_image(colormap) self.name = name self.removable = removable self.checked = QCheckBox() self.checked.setChecked(accepted) self.checked.setDisabled(used) self.setMinimumWidth(80) metrics = QFontMetrics(QFont()) layout = QHBoxLayout() layout.addWidget(self.checked) layout.addStretch(1) self.remove_btn = QToolButton() self.remove_btn.setIcon(_icon_selector.close_icon) if removable: self.remove_btn.setToolTip("Remove colormap") else: self.remove_btn.setToolTip("This colormap is protected") self.remove_btn.setEnabled(not accepted and self.removable) self.edit_btn = QToolButton() self.edit_btn.setIcon(_icon_selector.edit_icon) layout.addWidget(self.remove_btn) layout.addWidget(self.edit_btn) self.setLayout(layout) self.checked.stateChanged.connect(self._selection_changed) self.edit_btn.clicked.connect(partial(self.edit_request.emit, name)) if isinstance(colormap, ColorMap): self.edit_btn.clicked.connect( partial(self.edit_request[ColorMap].emit, colormap)) self.edit_btn.setToolTip("Create colormap base on this") else: self.edit_btn.setDisabled(True) self.edit_btn.setToolTip("This colormap is not editable") self.remove_btn.clicked.connect(partial(self.remove_request.emit, name)) self.setMinimumHeight( max(metrics.height(), self.edit_btn.minimumHeight(), self.checked.minimumHeight()) + 20)
def recalculate_size(self, font: QFont = None): """ If font is unspecified, Updates size unconditionally Otherwise, Updates size if the QFontMetrics is changed """ if font is not None: font_metrics = QFontMetrics(font) bold_font = QFont(font) bold_font.setBold(True) bold_font_metrics = QFontMetrics(bold_font) if self._bold_font_metrics == bold_font_metrics: return self._font_metrics = font_metrics self._bold_font_metrics = bold_font_metrics self._entry_height = self._font_metrics.height() max_num_of_entries = max((self.num_sinks, self.num_sources)) step = self._entry_height + self._spacing height = step * max_num_of_entries w = self._model.embedded_widget() if w: height = max((height, w.height())) height += self.caption_height self._input_port_width = self.port_width(PortType.input) self._output_port_width = self.port_width(PortType.output) width = self._input_port_width + self._output_port_width + 2 * self._spacing w = self._model.embedded_widget() if w: width += w.width() width = max((width, self.caption_width)) if self._model.validation_state() != NodeValidationState.valid: width = max((width, self.validation_width)) height += self.validation_height + self._spacing self._width = width self._height = height
def __init__(self, node: NodeBase): super().__init__() self._node = node self._model = node.model self._dragging_pos = QPointF(-1000, -1000) self._entry_width = 0 self._entry_height = 20 self._font_metrics = QFontMetrics(QFont()) self._height = 150 self._hovered = False self._input_port_width = 70 self._output_port_width = 70 self._spacing = 20 self._style = node.style self._width = 100 f = QFont() f.setBold(True) self._bold_font_metrics = QFontMetrics(f)
def drawDisplay(self, painter, option, rect, text): """ Draw the displayed text. Override of QItemDelegate::drawDisplay. Args: painter (QPainter): the painter option (QStyleOptionViewItem): drawing options rect (QRect): cell rectangle text (QString): text to display """ fontMetric = QFontMetrics(option.font) reducable = True boudingRectangle = fontMetric.boundingRect(text) while (boudingRectangle.width() > rect.width()) and (reducable): text, reducable = self.reduceNumorsStr(text) boudingRectangle = fontMetric.boundingRect(text) super(DrillItemDelegate, self).drawDisplay(painter, option, rect, text)
def minimumSizeHint(self): fm = QFontMetrics(self.font()) return QSize(fm.height(), fm.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()