Seite 1 von 1

PyQT5 textbrowser.append | command output encoding/decoding

Verfasst: Sonntag 2. Oktober 2022, 08:52
von BlackLeakz
Hallo liebe Community,

ich würde gerne in Python3 , pyqt5 im Textbrowser das output des commands ('netsh wlan show networks') ausgeben . Leider ist das nicht so einfach wie gedacht und bisherige Recherche hat sich nicht gut verkauft...
Vielen Dank im vorraus.

Die simple cli-version ist diese:
(Problematik mit ! "" makiert.)

Code: Alles auswählen

#import subprocess
import os
import sys
import time
from time import sleep


def scan():
    print("Scanning..")
    #os.system('netsh wlan disconnect')
    disconnect()
    time.sleep(1.5)
    os.system('netsh wlan show networks')



def disconnect():
    print("Disconnecting.")
    os.system('netsh wlan disconnect')


def connect():
    print("Connecting.")


def tracing():
    print("Show tracing.")
    os.system('netsh wlan show tracing')


def interfaces():
    print("Show interfaces.")
    os.system('netsh wlan show interfaces')

def wlanreport():
    print("Wlanreport.")
    os.system('netsh wlan show wlanreport')

def all():
    print("Show all.")
    os.system('netsh wlan show all')

def main():
    while True:
        print("===============================")
        print("== WifiManager - v0.1        ==")
        print("===============================")
        print("=| 1: scan      | 2: connect |=")
        print("=| 3: interfaces| 4: tracing |=")
        print("=| 5: wlanreport| 6: all     |=")
        print("===============================")

        x = input("admin@WifiManager:~$ ")

        if x == "1":
            scan()
        if x == "2":
            connect()
        if x == "3":
            interfaces()
        if x == "4":
            tracing()
        if x == "5":
            wlanreport()
        if x == "6":
            all()



if __name__ == '__main__':
    main()

Diese würde ich gerne Übersetzen / in diesen Code umwandeln:

Code: Alles auswählen

# main.py
import sys
from PyQt5 import QtWidgets
from MainWindow import Ui_MainWindow

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setupUi(self)


app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()


# Ui_file
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file '/mnt/x/Development/Projekte/WIFIMGR_/mainwindow/form.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets
import subprocess
import os
from subprocess import *

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.scanbtn = QtWidgets.QPushButton(self.centralwidget)
        self.scanbtn.setGeometry(QtCore.QRect(500, 410, 80, 24))
        self.scanbtn.setObjectName("scanbtn")
        self.scanbtn.clicked.connect(self.scanner)

        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        self.textBrowser.setGeometry(QtCore.QRect(70, 90, 641, 231))
        self.textBrowser.setObjectName("textBrowser")

        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "WifiManager"))
        self.scanbtn.setText(_translate("MainWindow", "scan"))

    def scanner(self):
        self.textBrowser.append("Start scanning.., disconnecting device to perform a full scan.")


!""
        #stdout = Popen('netsh wlan show networks', shell=True, stdout=PIPE).stdout
        output = stdout.read()

        #print(output)

!""
        #out = os.system('netsh wlan show networks')
        #new_ = out.encode(encoding='utf-8')
!""
        #self.textBrowser.append(subprocess.check_output('cmd /k netsh wlan show networks'))


Re: PyQT5 textbrowser.append | command output encoding/decoding

Verfasst: Sonntag 2. Oktober 2022, 08:57
von sparrow
Dann zeig doch mal, was du bisher hast.

Grundsätzlich startet man externe Prozesse mit dem "subprocess"-Modul. Die Dokumentation beschreibt auch, wie man an stdout kommt.

Re: PyQT5 textbrowser.append | command output encoding/decoding

Verfasst: Sonntag 2. Oktober 2022, 09:23
von BlackLeakz
sparrow hat geschrieben: Sonntag 2. Oktober 2022, 08:57 Dann zeig doch mal, was du bisher hast.

Grundsätzlich startet man externe Prozesse mit dem "subprocess"-Modul. Die Dokumentation beschreibt auch, wie man an stdout kommt.
added <3

Re: PyQT5 textbrowser.append | command output encoding/decoding

Verfasst: Sonntag 2. Oktober 2022, 10:42
von Sirius3
Bevor man anfängt, irgendwas mit externen Programmen abzufragen, schaut man, ob man an die Information auch direkt kommt. Und dafür hat Windows allerhand Schnittstellen, zu denen es auch oft schon Python-Wrapper gibt, wie hier https://pypi.org/project/win32wifi/.

Re: PyQT5 textbrowser.append | command output encoding/decoding

Verfasst: Dienstag 4. Oktober 2022, 10:19
von __blackjack__
@BlackLeakz: Erst einmal ist das erste nicht wirklich Python. Wenn man im Grunde nur `print()`, `input()`, Schleifen hat, und ansonsten nur externe Programme aufruft, dann ist das eigentlich ein Shell-Skript das sich als Python-Programm verkleidet hat. Passt irgendwie in die Jahreszeit — Halloween — muss aber nicht wirklich sein. Ungetestet:

Code: Alles auswählen

#!/bin/bash
 
Main() {
    local input
    
    while true; do
        echo '==============================='
        echo '== WifiManager - v0.1        =='
        echo '==============================='
        echo '=| 1: scan      | 2: connect |='
        echo '=| 3: interfaces| 4: tracing |='
        echo '=| 5: wlanreport| 6: all     |='
        echo '==============================='
        read -r -p 'admin@WifiManager:~$ ' input
        case $input in
            1)
                echo 'Scanning...'
                echo 'Disconnecting...'
                netsh wlan disconnect
                sleep 1.5
                netsh wlan show networks
                ;;
            2)
                echo 'Connecting...'
                ;;
            3)
                echo 'Show interfaces.'
                netsh wlan show interfaces
                ;;
            4)
                echo 'Show tracing.'
                netsh wlan show tracing
                ;;
            5)
                echo 'Wlanreport.'
                netsh wlan show wlanreport
                ;;
            6)
                echo 'Show all.'
                netsh wlan show all
                ;;
        esac
    done
}

[[ ${BASH_SOURCE[0]} = "$0" ]] && Main "$@"
Dann steht in der aus der *.ui-Datei generierten Quelltextdatei ganz deutlich eine Warnung das man da nichts ändern oder hinzufügen soll, weil man dann ja nichts mehr an der *.ui-Datei ändern kann wenn beim erneuten generieren die ganzen manuellen Änderungen verloren gehen.

Man generiert heutzutage diese Quelltextdatei nicht mehr, sondern lädt die *.ui-Datei zur Laufzeit mit Hilfe des `PyQt5.uic`-Moduls.

Sternchen-Importe sind Böse™. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Namen sollten keine kryptischen Abkürzungen enthalten. Wenn man `scanButton` meint, sollte man nicht `scanbtn` schreiben.

Im generierten Quelltext sieht man, dass sowohl Fenstergrösse als auch Grösse und Positionen der Widgets in dem Fenster fest vorgegeben sind statt Layouts zu verwenden. Feste Pixelangaben funktionieren nicht wirklich. Entweder hat man viel zu viel Platz um die Elemente, oder es kann bei anderen Bildschirmgrössen, -auflösungen, und Systemeinstellungen sogar unbenutzbar werden, wenn Elemente sich überlappen oder nicht mehr im sichtbaren Bereich des Fenster liegen.

``shell=True`` sollte man bei `subprocess` meiden, denn damit fängt man sich die gleichen Programe ein weswegen man `os.system()` nicht verwenden sollte.