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)
def on_search_suggestions(self): logging.info('Received search suggestions for keywords: "{}"'.format( self.keywords)) self.searchbar.setEnabled(True) self.searchbar.setFocus() if self.suggestions: suggestions = [ suggestion['label'] for suggestion in self.suggestions ] completer = QCompleter(suggestions) completer.setCaseSensitivity(Qt.CaseInsensitive) self.searchbar.setCompleter(completer) self.searchbar.completer().complete() self.searchbar.completer().popup().setStyleSheet( css( """ QListView { border: 1px solid {{borderColor}}; padding: 10px; background: {{backgroundColor}}; } QItemSelection { padding: 10px; } """, borderColor=colors.SECONDARY_COLOR, backgroundColor=colors.PLACEHOLDER_COLOR, ))
def __init__(self): WizardPage.__init__(self) self.fetch_config = None self.app_model = QStringListModel( REGISTRY.names( lambda klass: not getattr(klass, "disable_in_gui", None))) self.ui.app_combo.setModel(self.app_model) if mozinfo.bits == 64: if mozinfo.os == "mac": self.bits_model = QStringListModel(["64"]) bits_index = 0 else: self.bits_model = QStringListModel(["32", "64"]) bits_index = 1 elif mozinfo.bits == 32: self.bits_model = QStringListModel(["32"]) bits_index = 0 self.ui.bits_combo.setModel(self.bits_model) self.ui.bits_combo.setCurrentIndex(bits_index) self.build_type_model = QStringListModel() self.ui.app_combo.currentIndexChanged.connect(self._set_fetch_config) self.ui.bits_combo.currentIndexChanged.connect(self._set_fetch_config) self.ui.app_combo.setCurrentIndex( self.ui.app_combo.findText("firefox")) self.ui.repository.textChanged.connect(self._on_repo_changed) completer = QCompleter(sorted(get_branches()), self) completer.setCaseSensitivity(Qt.CaseInsensitive) self.ui.repository.setCompleter(completer) QApplication.instance().focusChanged.connect(self._on_focus_changed)
def _completerSetupFunction(self, editor, index): completer = QCompleter(getHeadersData(), editor) completer.setCompletionColumn(0) completer.setCompletionRole(Qt.EditRole) completer.setCaseSensitivity(Qt.CaseInsensitive) try: editor.setCompleter(completer) except: pass
def __init__(self, lookup_names: List[str], on_entered: CallbackType) -> None: widget = QLineEdit("") completer = QCompleter(lookup_names) completer.setCaseSensitivity(Qt.CaseInsensitive) completer.setFilterMode(Qt.MatchFlag.MatchContains) completer.setMaxVisibleItems(50) widget.setCompleter(completer) super().__init__("Название рецепта:", widget) self._on_recipe_name_entered = on_entered self._connect_slots()
def __init__(self, food_names: List[str], on_ingredient_entered: CallbackType, on_ingredient_finalized: CallbackType) -> None: super().__init__() self._food_names = food_names self._on_ingredient_entered = on_ingredient_entered self._on_ingredient_finalized = on_ingredient_finalized # ingredient ingredient_label = QLabel("Продукт:") ingredient_line_edit = QLineEdit() # Completer for the ingredient line edit completer = QCompleter(self._food_names) completer.setCaseSensitivity(Qt.CaseInsensitive) ingredient_line_edit.setCompleter(completer) # ingredient mass line edit ingredient_mass_line_edit = QLineEdit() ingredient_mass_line_edit.setPlaceholderText("Масса (гр.)") ingredient_mass_line_edit.setFixedWidth(100) ingredient_mass_line_edit.setValidator(QIntValidator()) ingredient_mass_line_edit.setMaxLength(4) # Button to add ingredient to the recipe ingredient_add_button = QPushButton("+") # Layout for ingredient_label / ingredient_line_edit ingredient_layout = QHBoxLayout() ingredient_layout.addWidget(ingredient_label) ingredient_layout.addWidget(ingredient_line_edit) ingredient_layout.addWidget(ingredient_mass_line_edit) ingredient_layout.addWidget(ingredient_add_button) self.setLayout(ingredient_layout) self._ingredient_line_edit = ingredient_line_edit self._ingredient_mass_line_edit = ingredient_mass_line_edit self._ingredient_add_button = ingredient_add_button self._connect_slots()
def __init__(self, lookup_names: List, on_item_added: CallbackType) -> None: super().__init__() recipe_search_label = QLabel("Блюдо:") recipe_search_line_edit = QLineEdit("") completer = QCompleter(lookup_names) completer.setCaseSensitivity(Qt.CaseInsensitive) completer.setFilterMode(Qt.MatchFlag.MatchContains) completer.setMaxVisibleItems(50) recipe_search_line_edit.setCompleter(completer) serves_amount_label = QLabel("Порций:") serves_amount_line_edit = QLineEdit(str(self.DEFAULT_SERVES_AMOUNT)) serves_amount_line_edit.setFixedWidth(30) serves_amount_line_edit.setValidator(QIntValidator()) serves_amount_line_edit.setMaxLength(2) add_push_button = QPushButton("+") # Widget layout layout = QHBoxLayout() layout.addWidget(recipe_search_label) layout.addWidget(recipe_search_line_edit) layout.addWidget(serves_amount_label) layout.addWidget(serves_amount_line_edit) layout.addWidget(add_push_button) layout.addStretch() self.setLayout(layout) # Init self data self._on_item_added = on_item_added self._recipe_search_line_edit = recipe_search_line_edit self._serves_amount_line_edit = serves_amount_line_edit self._add_push_button = add_push_button # Connect slots self._connect_slots()
def more_trans_complete(self): curr_text = self.view.method_of_trans.currentText() helping = [] if curr_text == "Salary": for value in ( "Bash Imam", "Ass. Imam", "Muazzin", "Ass. Muazzin", "Sibithi", "Akshah", "Sadarth", ): helping.append(value) elif curr_text == "Till Box": for value in ("1", "2"): helping.append(value) elif curr_text == "Maintenance": for value in ("Labourer charge", "Material charge", "Cleaning"): helping.append(value) completer = QCompleter(helping) completer.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive) self.view.more_trans_detail.setCompleter(completer)
class AbstractReferenceSelector(ABC, QWidget, metaclass=SelectorMeta): changed = Signal() def __init__(self, parent=None): QWidget.__init__(self, parent) self.completer = None self.p_selected_id = 0 self.layout = QHBoxLayout() self.layout.setMargin(0) self.name = QLineEdit() self.name.setText("") self.layout.addWidget(self.name) self.details = QLabel() self.details.setText("") self.details.setVisible(False) self.layout.addWidget(self.details) self.button = QPushButton("...") self.button.setFixedWidth(self.button.fontMetrics().width("XXXX")) self.layout.addWidget(self.button) self.setLayout(self.layout) self.setFocusProxy(self.name) self.button.clicked.connect(self.on_button_clicked) if self.details_field: self.name.setFixedWidth(self.name.fontMetrics().width("X") * 15) self.details.setVisible(True) self.completer = QCompleter(self.dialog.model.completion_model) self.completer.setCompletionColumn( self.dialog.model.completion_model.fieldIndex(self.selector_field)) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.name.setCompleter(self.completer) self.completer.activated[QModelIndex].connect(self.on_completion) def getId(self): return self.p_selected_id def setId(self, selected_id): if self.p_selected_id == selected_id: return self.p_selected_id = selected_id self.name.setText( self.dialog.model.getFieldValue(selected_id, self.selector_field)) if self.details_field: self.details.setText( self.dialog.model.getFieldValue(selected_id, self.details_field)) selected_id = Property(int, getId, setId, notify=changed, user=True) def on_button_clicked(self): ref_point = self.mapToGlobal(self.name.geometry().bottomLeft()) self.dialog.setGeometry(ref_point.x(), ref_point.y(), self.dialog.width(), self.dialog.height()) res = self.dialog.exec_(enable_selection=True, selected=self.selected_id) if res: self.selected_id = self.dialog.selected_id self.changed.emit() @Slot(QModelIndex) def on_completion(self, index): model = index.model() self.selected_id = model.data(model.index(index.row(), 0), Qt.DisplayRole) self.changed.emit() def isCustom(self): return True
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!
class ConsoleDialog(QDialog): def __init__(self, title: str, program: str, args: List[str], commands: List[str]): super().__init__() self.setWindowTitle(title) self.program = program self.args = args self.layout = QGridLayout() self.output = QTextEdit() self.output.acceptRichText = True self.input = QLineEdit() self.completer = QCompleter(commands, self) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.input.setCompleter(self.completer) self.input.setFocus() self.layout.addWidget(self.output) self.layout.addWidget(self.input) self.setLayout(self.layout) self.connect(self.input, SIGNAL("returnPressed(void)"), self.execute_user_command) self.connect(self.completer, SIGNAL("activated(const QString&)"), self.input.clear, Qt.QueuedConnection) def execute_user_command(self): cmd = str(self.input.text()) self.run_command(cmd) def run_command(self, cmd: str): log.info( 'run_command', program=self.program, args=self.args, cmd=cmd ) self.output.append(f'> {cmd}\n') self.input.clear() process = QProcess() process.setProgram(self.program) process.setCurrentReadChannel(0) # noinspection PyUnresolvedReferences process.readyReadStandardError.connect( lambda: self.handle_error(process) ) # noinspection PyUnresolvedReferences process.readyReadStandardOutput.connect( lambda: self.handle_output(process) ) connect_args = list(self.args) args = cmd.split(' ') if args[0] == self.program.split('/')[-1]: args.pop(0) process.setArguments(connect_args + args) process.start() def handle_error(self, process: QProcess): output: QByteArray = process.readAllStandardError() message = output.data().decode('utf-8').strip() self.output.append(message) def handle_output(self, process: QProcess): output: QByteArray = process.readAllStandardOutput() message = output.data().decode('utf-8').strip() if message.startswith('{') or message.startswith('['): formatter = HtmlFormatter() formatter.noclasses = True formatter.linenos = False formatter.nobackground = True message = highlight(message, JsonLexer(), formatter) self.output.insertHtml(message) else: self.output.append(message) # This is just for generating the command lists in constants # commands = None # if '== Blockchain ==' in message: # commands = self.parse_litecoin_cli_commands(message) # elif 'lncli [global options] command [command options]' in message: # commands = self.parse_lncli_commands(message) # if commands is not None: # log.debug('commands', commands=commands) max_scroll = self.output.verticalScrollBar().maximum() self.output.verticalScrollBar().setValue(max_scroll) @staticmethod def parse_litecoin_cli_commands(message: str): log.debug('parse_litecoin_cli_commands') commands = [] for line in message.split(sep='\n'): line = line.strip() if not line or line.startswith('=='): continue command = line.split()[0] command = command.strip() commands.append(command) return commands @staticmethod def parse_lncli_commands(message: str): log.debug('parse_lncli_commands') at_commands = False commands = [] for line in message.split(sep='\n'): line = line.strip() if not at_commands: if 'COMMANDS:' in line: at_commands = True log.debug('commands line', line=line) continue elif 'GLOBAL OPTIONS' in line: return commands elif line.endswith(':') or not line: continue command = line.split()[0] command = command.strip().replace(',', '') commands.append(command) return commands def show(self): self.showMaximized() self.raise_() self.setWindowState(self.windowState() & ~Qt.WindowMinimized | Qt.WindowActive) self.activateWindow() self.input.setFocus() self.run_command('help')
class LibraryItems(QObject): item_selected = Signal(object) item_activated = Signal(object) def __init__(self, app, window, lib_tree): QObject.__init__(self) self.app = app self.lib_tree = lib_tree self.library = app.library self.input = window.search_query_input self.view = window.lib_items self.tree_conditions = [] self.items = [] self.items_incomplete = False self.model = ItemModel(self.app) self.model.setColumnCount(1) self.compl_model = QStandardItemModel() self.compl_model.setColumnCount(1) self.completer = QCompleter(self.compl_model) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setModelSorting(QCompleter.CaseSensitivelySortedModel) self.input.setCompleter(self.completer) self.view.setHeaderHidden(True) self.view.setIndentation(0) self.view.setModel(self.model) self.view.sortByColumn(0, Qt.AscendingOrder) self.view.setDragEnabled(True) self.view.setAcceptDrops(True) self.view.setSelectionMode(QAbstractItemView.ExtendedSelection) self.view.setEditTriggers(QAbstractItemView.NoEditTriggers) selection_model = self.view.selectionModel() selection_model.selectionChanged.connect(self.selection_changed) tree_selection_model = window.lib_tree.selectionModel() tree_selection_model.selectionChanged.connect( self.tree_selection_changed) self.input.editingFinished.connect(self.query_entered) self.input.textChanged.connect(self.query_changed) self.view.doubleClicked.connect(self.double_clicked) self.run_query() def reload(self): self.model.clear() self.item_selected.emit(None) icon = QIcon.fromTheme("audio-x-generic") for item in self.items: s_item = QStandardItem(icon, item.name) s_item.setDragEnabled(True) s_item.setDropEnabled(False) s_item.setData(item) self.model.appendRow([s_item]) if self.items_incomplete: s_item = QStandardItem("…and more") s_item.setDragEnabled(False) s_item.setDropEnabled(False) self.model.appendRow([s_item]) @Slot(QItemSelection) def selection_changed(self, selection): logger.debug("selection changed") indexes = selection.indexes() if indexes: index = selection.indexes()[0] s_item = self.model.itemFromIndex(index) metadata = s_item.data() else: metadata = None self.item_selected.emit(metadata) @Slot(QModelIndex) def double_clicked(self, index): s_item = self.model.itemFromIndex(index) metadata = s_item.data() self.item_activated.emit(metadata) @Slot(QItemSelection) def tree_selection_changed(self, selection): logger.debug("tree selection changed") self.tree_conditions = self.lib_tree.get_current_conditions() self.run_query() def run_query(self): text_query = self.input.text() query = SearchQuery.from_string(text_query) query.add_conditions(self.tree_conditions) items = self.library.get_items(query, limit=ITEM_LIMIT + 1) if len(items) > ITEM_LIMIT: self.items_incomplete = True self.items = items[:ITEM_LIMIT] else: self.items_incomplete = False self.items = items self.reload() @Slot() def query_entered(self): self.run_query() @Slot() def query_changed(self, text): compl_query = CompletionQuery.from_string(text) if compl_query: columns = ["offsets(compl_fts.fts)", "compl_fts.content"] compl_query.add_conditions(self.tree_conditions) sql_query, params = compl_query.as_sql(columns=columns) logger.debug("completing %r with query %r %r", compl_query.prefix, sql_query, params) matches = self.library.get_completions(compl_query, limit=COMPLETION_LIMIT) self.compl_model.clear() for match in sorted(matches): match = text[:compl_query.start_index] + match logger.debug("Adding match: %r", match) s_item = QStandardItem(match) self.compl_model.appendRow([s_item]) else: self.model.clear()
class ConsoleDialog(QDialog): def __init__(self, node): super().__init__() self.node = node self.show_help = True self.layout = QGridLayout() self.setLayout(self.layout) self.output_area = QTextEdit() self.output_area.setReadOnly(True) self.output_area.acceptRichText = True self.output_area.document().setMaximumBlockCount(5000) self.layout.addWidget(self.output_area) self.input_area = QLineEdit() self.completer = QCompleter() # noinspection PyUnresolvedReferences self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.input_area.setCompleter(self.completer) self.input_area.setFocus() self.layout.addWidget(self.input_area) self.connect(self.input_area, SIGNAL("returnPressed(void)"), self.execute_user_command) @property def cli(self): try: return self.node.software.cli except AttributeError: return None @property def cli_args(self): try: return self.node.configuration.cli_args except AttributeError: return None def showEvent(self, event): super().showEvent(event) if self.show_help: success = self.run_command('help') if success: self.show_help = False def execute_user_command(self): cmd = str(self.input_area.text()) self.input_area.clear() self.run_command(cmd) def run_command(self, command): try: if self.cli is None or self.cli_args is None: self.output_area.append( 'Node starting up, please try again later...') return False self.output_area.append(f'> {command}\n') process = QProcess() process.setProgram(self.cli) process.setCurrentReadChannel(0) # noinspection PyUnresolvedReferences process.readyReadStandardError.connect( lambda: self.handle_cli_error_output(process)) # noinspection PyUnresolvedReferences process.readyReadStandardOutput.connect( lambda: self.handle_cli_output(process)) args = command.split(' ') if args[0] == self.cli.split('/')[-1]: args.pop(0) process.setArguments(self.cli_args + args) process.start() log.info('run_command', program=self.cli, args=self.cli_args, cmd=command) return True except Exception: self.output_area.append( 'Node starting up, please try again later...') return False def handle_cli_error_output(self, cli_process: QProcess): output: QByteArray = cli_process.readAllStandardError() message = output.data().decode('utf-8').strip() self.output_area.append(message) def handle_cli_output(self, cli_process: QProcess): output: QByteArray = cli_process.readAllStandardOutput() message = output.data().decode('utf-8').strip() if message.startswith('{') or message.startswith('['): formatter = HtmlFormatter() formatter.noclasses = True formatter.linenos = False formatter.nobackground = True message = highlight(message, JsonLexer(), formatter) self.output_area.insertHtml(message) else: self.output_area.append(message)
class TraceWindow(QMainWindow): def __init__(self, qmp): QMainWindow.__init__(self) self.qmp = qmp os.system('rm /tmp/errors.log 2>/dev/null') self.trace_events = self.qmp.hmp_command('info trace-events') self.qmp.hmp_command('logfile /tmp/errors.log') self.trace_events = sorted( self.trace_events['return'].split('\r\n'))[1:] self.activated = [] self.length = 100 self.timer = QTimer(self) self.timer.timeout.connect(self.disp_output) self.timer.start(100) self.init_ui() def init_ui(self): self.setWindowTitle('Trace Event Window') self.setGeometry(100, 100, 800, 600) bar = self.menuBar() file_ = bar.addMenu('File') export_log = QAction('Save to File', self, triggered=lambda: self.save_log()) options = bar.addMenu('Options') auto_refresh = QAction( 'Auto Refresh', self, checkable=True, triggered=lambda: self.timer.start(100) if auto_refresh.isChecked() else self.timer.stop()) auto_refresh.setChecked(True) options.addAction(auto_refresh) file_.addAction(export_log) vgrid = QVBoxLayout() grid = QHBoxLayout() self.tree = QTreeWidget() self.tree.setHeaderLabels(['Name']) self.top = [] self.lst = [] for n, event in enumerate(self.trace_events): word = event.split('_')[0] if word not in self.top: self.top.append(word) item = QTreeWidgetItem(self.tree) self.lst.append(item) item.setText(0, word) subitem = QTreeWidgetItem(item) subitem.setText(0, ' ' + event.split(' : ')[0]) # subitem.setCheckState(0, Qt.Unchecked) cbox = QCheckBox() cbox.stateChanged.connect(lambda state, text=subitem.text(0): self. handle_checked(state, text)) self.tree.setItemWidget(subitem, 0, cbox) # self.tree.setColumnWidth(0, 25) self.tracelist = QLabel() self.disp_output() self.traceview = QScrollArea() self.traceview.setWidget(self.tracelist) self.traceview.setWidgetResizable(True) search = QHBoxLayout() self.search_bar = QLineEdit(self) self.completer = QCompleter(self.top, self) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.search_bar.setCompleter(self.completer) search_button = QPushButton('Search') search_button.clicked.connect(lambda: self.tree.setCurrentItem( self.lst[self.top.index(self.search_bar.text())])) expand = QPushButton('▼') expand.setFixedSize(QSize(25, 25)) expand.clicked.connect(lambda: self.tree.expandAll()) collapse = QPushButton('▲') collapse.setFixedSize(QSize(25, 25)) collapse.clicked.connect(lambda: self.tree.collapseAll()) self.search_bar.returnPressed.connect(lambda: search_button.click()) search.addWidget(self.search_bar) search.addWidget(search_button) search.addWidget(expand) search.addWidget(collapse) self.digest = QLabel() vgrid.addLayout(search) vgrid.addWidget(self.tree) vgridwid = QWidget() vgridwid.setLayout(vgrid) split = QSplitter(Qt.Horizontal) split.addWidget(vgridwid) split.addWidget(self.traceview) split.setStretchFactor(1, 1) # grid.addLayout(vgrid) grid.addWidget(split) # grid.addWidget(self.tracelist) self.disp_output() center = QWidget() center.setLayout(grid) self.setCentralWidget(center) self.show() def disp_output(self): self.shorten_file() with open('/tmp/errors.log', 'r') as errors: self.digest = [] lines = 0 for line in errors: if re.match(r"\d+@\d+\.\d+:.*", line): self.digest.append(line) lines += 1 if not self.digest: self.digest = ['<font color="grey">Empty...</font>'] self.digest = ''.join(self.digest[-self.length:]) self.tracelist.setText(self.digest) self.tracelist.setFont(QFont('Monospace', 10)) self.tracelist.setTextInteractionFlags(Qt.TextSelectableByMouse) def shorten_file(self): with open('/tmp/errors.log', 'r+') as tracefile: content = ''.join(tracefile.readlines()[-(self.length * 3):]) tracefile.seek(0) tracefile.truncate() tracefile.write(content) def save_log(self): name = QFileDialog.getSaveFileName(self, 'Save File', '', 'Text files (*.txt)') log_file = open(name[0], 'w') log_file.write(self.digest) log_file.close() def handle_checked(self, state, text): if state: self.qmp.hmp_command('trace-event %s on' % text.strip()) self.activated.append(text) else: self.qmp.hmp_command('trace-event %s off' % text.strip()) self.activated.remove(text) def closeEvent(self, event): self.timer.stop() for e in self.activated: self.qmp.hmp_command('trace-event %s off' % e.strip()) os.system('rm /tmp/errors.log') event.accept()