def setupController(self, logger, statusbar, progressbar): controller = QtToolController(logger, parent=self) controller.subprocess.started.connect(self.processingStarted) controller.finished.connect(self.processingDone) self.stopbutton.clicked.connect(controller.stop_tool) return controller
def __init__(self, debug=False): super(QtShell, self).__init__() # Icon self.setWindowIcon( self.style().standardIcon(QtWidgets.QStyle.SP_ComputerIcon)) # Command box self.cmdbox = QtWidgets.QComboBox() self.cmdbox.setEditable(True) self.cmdbox.addItem('') self.cmdbox.setCurrentIndex(self.cmdbox.count() - 1) # @TODO: complete #self.entry.populate_popup.connect(self.on_populate_popup) icon = self.style().standardIcon(QtWidgets.QStyle.SP_MediaPlay) self.cmdbutton = QtWidgets.QPushButton(icon, 'Run') self.cmdbutton.clicked.connect(self.execute) lineedit = self.cmdbox.lineEdit() lineedit.returnPressed.connect(self.cmdbutton.click) hLayout = QtWidgets.QHBoxLayout() hLayout.addWidget(QtWidgets.QLabel('cmd > ')) hLayout.addWidget(self.cmdbox, 1) hLayout.addWidget(self.cmdbutton) # Output pane outputpane = QtOutputPane() outputpane.setReadOnly(True) outputpane.actions.removeAction(outputpane.actionHide) vLayout = QtWidgets.QVBoxLayout() vLayout.addLayout(hLayout) vLayout.addWidget(outputpane) # Main window centralWidget = QtWidgets.QWidget() centralWidget.setLayout(vLayout) self.setCentralWidget(centralWidget) self.quit_shortcut = QtWidgets.QShortcut(QtGui.QKeySequence.Quit, self) self.eof_shortcut = QtWidgets.QShortcut( QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_D), self) self.setWindowTitle('Qt Shell') self.setGeometry(0, 0, 800, 600) self.quit_shortcut.activated.connect(self.close) self.eof_shortcut.activated.connect(self.close) # Setup the log system if debug: level = logging.DEBUG logging.basicConfig(level=level) else: level = logging.INFO self.logger = logging.getLogger() formatter = logging.Formatter('%(levelname)s: %(message)s') handler = QtLoggingHandler(outputpane) handler.setLevel(level) handler.setFormatter(formatter) self.logger.addHandler(handler) formatter = logging.Formatter('%(message)s') handler = QtDialogLoggingHandler(parent=self, dialog=None) handler.setLevel(logging.WARNING) handler.setFormatter(formatter) self.logger.addHandler(handler) self.logger.setLevel(level) # Setup high level components and initialize the parent classes handler = QtOutputHandler(self.logger, self.statusBar()) self.tool = exectools.ToolDescriptor('', stdout_handler=handler) self.controller = QtToolController(self.logger, parent=self) self.controller.finished.connect(lambda returncode: self.reset()) #self.shell = True self._state = 'ready' # or maybe __state self.logger.debug('qtshell session started at %s.' % time.asctime()) self.load_history()
class QtShell(QtWidgets.QMainWindow): '''Qt interactive shell using tool controller. :SLOTS: * :meth:`execute` ''' historyfile = 'history.txt' def __init__(self, debug=False): super(QtShell, self).__init__() # Icon self.setWindowIcon( self.style().standardIcon(QtWidgets.QStyle.SP_ComputerIcon)) # Command box self.cmdbox = QtWidgets.QComboBox() self.cmdbox.setEditable(True) self.cmdbox.addItem('') self.cmdbox.setCurrentIndex(self.cmdbox.count() - 1) # @TODO: complete #self.entry.populate_popup.connect(self.on_populate_popup) icon = self.style().standardIcon(QtWidgets.QStyle.SP_MediaPlay) self.cmdbutton = QtWidgets.QPushButton(icon, 'Run') self.cmdbutton.clicked.connect(self.execute) lineedit = self.cmdbox.lineEdit() lineedit.returnPressed.connect(self.cmdbutton.click) hLayout = QtWidgets.QHBoxLayout() hLayout.addWidget(QtWidgets.QLabel('cmd > ')) hLayout.addWidget(self.cmdbox, 1) hLayout.addWidget(self.cmdbutton) # Output pane outputpane = QtOutputPane() outputpane.setReadOnly(True) outputpane.actions.removeAction(outputpane.actionHide) vLayout = QtWidgets.QVBoxLayout() vLayout.addLayout(hLayout) vLayout.addWidget(outputpane) # Main window centralWidget = QtWidgets.QWidget() centralWidget.setLayout(vLayout) self.setCentralWidget(centralWidget) self.quit_shortcut = QtWidgets.QShortcut(QtGui.QKeySequence.Quit, self) self.eof_shortcut = QtWidgets.QShortcut( QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_D), self) self.setWindowTitle('Qt Shell') self.setGeometry(0, 0, 800, 600) self.quit_shortcut.activated.connect(self.close) self.eof_shortcut.activated.connect(self.close) # Setup the log system if debug: level = logging.DEBUG logging.basicConfig(level=level) else: level = logging.INFO self.logger = logging.getLogger() formatter = logging.Formatter('%(levelname)s: %(message)s') handler = QtLoggingHandler(outputpane) handler.setLevel(level) handler.setFormatter(formatter) self.logger.addHandler(handler) formatter = logging.Formatter('%(message)s') handler = QtDialogLoggingHandler(parent=self, dialog=None) handler.setLevel(logging.WARNING) handler.setFormatter(formatter) self.logger.addHandler(handler) self.logger.setLevel(level) # Setup high level components and initialize the parent classes handler = QtOutputHandler(self.logger, self.statusBar()) self.tool = exectools.ToolDescriptor('', stdout_handler=handler) self.controller = QtToolController(self.logger, parent=self) self.controller.finished.connect(lambda returncode: self.reset()) #self.shell = True self._state = 'ready' # or maybe __state self.logger.debug('qtshell session started at %s.' % time.asctime()) self.load_history() def closeEvent(self, event): try: self.save_history() finally: self.logger.debug('qtshell session stopped at %s.' % time.asctime()) event.accept() # @TODO: check def load_history(self): self.cmdbox.clear() try: for cmd in open(self.historyfile, 'r'): self.cmdbox.addItem(cmd.rstrip()) self.logger.debug('history file "%s" loaded.' % self.historyfile) except (OSError, IOError) as e: self.logger.debug('unable to read the history file "%s": %s.' % (self.historyfile, e)) self.cmdbox.addItem('') self.cmdbox.setCurrentIndex(self.cmdbox.count() - 1) def save_history(self): try: history = [ str(self.cmdbox.itemText(index)) for index in range(self.cmdbox.count()) ] history = '\n'.join(history) f = open(self.historyfile, 'w') f.write(history) f.close() self.logger.debug('history saved in %s' % self.historyfile) except (OSError, IOError) as e: self.logger.warning('unable to save the history file "%s": %s' % (self.historyfile, e)) def _reset(self): self.controller.reset() # @TODO: use icons here self.cmdbutton.setText('Run') self.cmdbox.setEnabled(True) try: self.cmdbutton.clicked.disconnect(self.controller.stop_tool) except TypeError: # signal already disconnected pass else: self.cmdbutton.clicked.connect(self.execute) def reset(self): self.state = 'ready' @property def state(self): return self._state @state.setter def state(self, state): if state == 'ready': self._reset() self.statusBar().showMessage('Ready') # , 2000) # ms self.cmdbox.setFocus() elif state == 'running': self.cmdbox.setEnabled(False) self.cmdbutton.setText('Stop') self.cmdbutton.clicked.disconnect(self.execute) self.cmdbutton.clicked.connect(self.controller.stop_tool) self.statusBar().showMessage('Running ...') # , 2000) # ms else: raise ValueError('invalid status: "%s".' % state) self._state = state def get_command(self): cmd = str(self.cmdbox.currentText()) if cmd: count = self.cmdbox.count() if self.cmdbox.currentIndex() != count - 1: self.cmdbox.insertItem(count - 1, cmd) else: self.cmdbox.removeItem(count - 2) self.cmdbox.addItem('') self.cmdbox.setCurrentIndex(self.cmdbox.count() - 1) return cmd @QtCore.Slot() def execute(self): '''Execute the command line using the tool controller. :C++ signature: `void execute()` ''' cmd = self.get_command() if cmd: self.state = 'running' try: self.controller.run_tool(self.tool, cmd) #~ raise RuntimeError('simulated runtime error') except (KeyboardInterrupt, SystemExit): raise except Exception as e: self.logger.exception(e) self.reset()