helloSystem / Utilities

Utilities written in PyQt5, meant for use with helloSystem
BSD 2-Clause "Simplified" License
28 stars 29 forks source link

Installer: Remove the need for xterm #12

Open probonopd opened 3 years ago

probonopd commented 3 years ago

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_()
probonopd commented 3 years ago

Using QTerminal for now, but removing that dependency would be good.

probonopd commented 3 years ago

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.