class HelpWidget(QDockWidget): def __init__(self): super(HelpWidget, self).__init__() # TODO: ovo treba da bude kao neki widget u koji moze da se unese instrukcija ili registar ili direktiva # TODO: pa mu se onda ispise neki uredjeni HTML kao onaj tekst iz praktikuma sta ta kljucna rec znaci # TODO: mozda da se ispisu i neki odabrani algoritmi npr. sabiranje u dvostrukoj preciznosti sa ilustracijama # TODO: ili iteriranje kroz niz self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.setMinimumWidth(200) self.setStyleSheet("background-color: #2D2D30; color: white;") self.searchLabel = QLineEdit() self.searchLabel.setPlaceholderText("Search for an instruction...") self.completer = QCompleter(list(InstructionsInfo.INFO.keys()), self) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.popup().setStyleSheet( "background-color: #2D2D30; color: white") self.searchLabel.setCompleter(self.completer) self.searchLabel.setStyleSheet( "margin-bottom: 10px; margin-top: 10px;") self.setTitleBarWidget(self.searchLabel) self.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetClosable) self.setWindowTitle("Instructions help") self.resultBox = QTextEdit() self.resultBox.setReadOnly(True) self.setWidget(self.resultBox) def keyPressEvent(self, event): if event.key() == Qt.Key_Return and self.searchLabel.hasFocus(): seachWord = self.searchLabel.text().strip() if seachWord in InstructionsInfo.INFO: self.resultBox.setHtml(InstructionsInfo.INFO[seachWord]) super(HelpWidget, self).keyPressEvent(event)
class QFilteredComboBox(QComboBox): def __init__( self, parent=None, include_targets=True, include_airbases=True, include_frontlines=True, include_units=True, include_enemy=True, include_friendly=True, ): super(QFilteredComboBox, self).__init__(parent) self.setFocusPolicy(Qt.StrongFocus) self.setEditable(True) self.completer = QCompleter(self) self.include_targets = include_targets self.include_airbases = include_airbases self.include_frontlines = include_frontlines self.include_units = include_units self.include_enemy = include_enemy self.include_friendly = include_friendly # always show all completions self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.pFilterModel = QSortFilterProxyModel(self) self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.completer.setPopup(self.view()) self.setCompleter(self.completer) self.lineEdit().textEdited.connect(self.pFilterModel.setFilterFixedString) self.completer.activated.connect(self.setTextIfCompleterIsClicked) def setModel(self, model): super(QFilteredComboBox, self).setModel(model) self.pFilterModel.setSourceModel(model) self.completer.setModel(self.pFilterModel) self.model().sort(0) def setModelColumn(self, column): self.completer.setCompletionColumn(column) self.pFilterModel.setFilterKeyColumn(column) super(QFilteredComboBox, self).setModelColumn(column) def view(self): return self.completer.popup() def index(self): return self.currentIndex() def setTextIfCompleterIsClicked(self, text): if text: index = self.findText(text) self.setCurrentIndex(index)
class SearchEdit(QLineEdit): def __init__(self, parent: QWidget): QLineEdit.__init__(self, parent) self.completer = None def init_completer(self, words: Iterable[str]) -> None: assert self.completer is None self.completer = QCompleter(list(words), self) self.completer.setWidget(self) self.completer.setCompletionMode(QCompleter.PopupCompletion) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.activated.connect(self.on_insert_completion) def completer(self) -> QCompleter: return self.completer def on_insert_completion(self, completion): if self.completer.widget() != self: return prefix = self.completer.completionPrefix() extra_text = completion[len(prefix):] + ', ' self.insert(extra_text) def text_under_cursor(self) -> str: text = self.text() cursor_pos = self.cursorPosition() start_index = None comma_index1 = text[:cursor_pos].rfind(',') if comma_index1 >= 0: start_index = comma_index1 + 1 end_index = None comma_index2 = text[cursor_pos:].find(',') if comma_index2 >= 0: end_index = cursor_pos + comma_index2 return text[start_index:end_index].strip() def focus_in_event(self, event: QFocusEvent) -> None: if self.completer: self.completer.setWidget(self) QLineEdit.focusInEvent(self, event) def keyPressEvent(self, key_event: QKeyEvent) -> None: if self.completer and self.completer.popup().isVisible(): # The following keys are forwarded by the completer to the widget key = key_event.key() if key in (Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab, Qt.Key_Backtab): key_event.ignore() return # let the completer do default behavior is_ctrl_modifier = (key_event.modifiers() & Qt.ControlModifier) != 0 is_shift_modifier = (key_event.modifiers() & Qt.ShiftModifier) != 0 ctrl_or_shift = is_ctrl_modifier or is_shift_modifier is_shortcut = is_ctrl_modifier and key_event.key( ) == Qt.Key_E # CTRL+E if not self.completer or not is_shortcut: # do not process the shortcut when we have a completer QLineEdit.keyPressEvent(self, key_event) if not self.completer or ctrl_or_shift and key_event.text() == '': return eow = "~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-=" # end of word has_modifier = (key_event.modifiers() != Qt.NoModifier) and not ctrl_or_shift completion_prefix = self.text_under_cursor() if not is_shortcut: event_text = key_event.text() if has_modifier or not event_text or len( completion_prefix) < 1 or event_text[-1] in eow: self.completer.popup().hide() return if completion_prefix != self.completer.completionPrefix(): self.completer.setCompletionPrefix(completion_prefix) self.completer.popup().setCurrentIndex( self.completer.completionModel().index(0, 0)) cr = self.cursorRect() cr.setWidth( self.completer.popup().sizeHintForColumn(0) + self.completer.popup().verticalScrollBar().sizeHint().width()) self.completer.complete(cr) # popup it up!