Utilities
Utilities copied to clipboard
Installer: Remove the need for xterm
The following executes an external process and displays its output in a Qt widget.
#!/usr/bin/env python3.7
# Based on https://stackoverflow.com/a/41751956
import sys
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QProcess, QTextCodec
from PyQt5.QtGui import QTextCursor
from PyQt5.QtWidgets import QApplication, QPlainTextEdit
class ProcessOutputReader(QProcess):
produce_output = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setProcessChannelMode(QProcess.MergedChannels)
codec = QTextCodec.codecForLocale()
self._decoder_stdout = codec.makeDecoder()
self.readyReadStandardOutput.connect(self._ready_read_standard_output)
@pyqtSlot()
def _ready_read_standard_output(self):
raw_bytes = self.readAllStandardOutput()
text = self._decoder_stdout.toUnicode(raw_bytes)
self.produce_output.emit(text)
class MyConsole(QPlainTextEdit):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setReadOnly(True)
self.setMaximumBlockCount(10000) # limit console to 10000 lines
self._cursor_output = self.textCursor()
@pyqtSlot(str)
def append_output(self, text):
self._cursor_output.insertText(text)
self.scroll_to_last_line()
def scroll_to_last_line(self):
cursor = self.textCursor()
cursor.movePosition(QTextCursor.End)
cursor.movePosition(QTextCursor.Up if cursor.atBlockStart() else
QTextCursor.StartOfLine)
self.setTextCursor(cursor)
app = QApplication(sys.argv)
reader = ProcessOutputReader()
console = MyConsole()
reader.produce_output.connect(console.append_output)
reader.start('ping', ['heise.de'])
console.show()
app.exec_()
Using QTerminal for now, but removing that dependency would be good.
Had to do https://github.com/helloSystem/Utilities/commit/f4866aeec3fd63d102fd71245b5f2fc01bf7a4b7 which makes it specific to systems that have the launch command (that is, helloSystem). Would be nice to get away from QTerminal/xterm/... and show the logs natively in PyQt.