Textdatei in QTextEdit einlesen - Programm stürzt ab

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Statt deinem gejoine kannst du auch gleich read benutzen. Wie jetzt schon mehrfach angemerkt. Und wenn es mit obigem Code klappt aber nicht dem von Sirius3, dann ist da was anderes im Argen.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Fehlermeldung kann nicht sein, denn bei deiner "Lösung" benutzt Du auch `texteditor`. Erst mühselig die Datei in Teilen aufzuspalten um sie im selben Schritt wieder in einen String zusammenzupappen statt direkt dem String zu lesen, ändert daran nichts.
Dass menu_oeffnen kein self-Attribut hat, sieht falsch aus, Du hast also irgenetwas komisches in dem Code, den du nicht teilst.
PythonMarlem
User
Beiträge: 90
Registriert: Dienstag 19. Mai 2020, 19:17
Wohnort: Dußlingen
Kontaktdaten:

Ich habe den Tipp bekommen, dass wenn man ein Python-Programm außerhalb der IDE startet, man detailliertere Fehlermeldungen bekommt.

Wenn ich diesen Code im Dosfenster teste:

Code: Alles auswählen

        def menuoffnen():
            dateiname = QFileDialog.getOpenFileName(self, 'Datei öffnen', '', 'Textdateien (*.txt)')
            dateiname = os.path.abspath(dateiname[0])
            programmeinstellungen.pfadgeoeffnetedatei = dateiname
            dateininhalt = ''.join(open(dateiname, encoding="utf8").readlines())
            self.texteditor.setPlainText(dateininhalt)
            self.setWindowTitle(os.path.basename(dateiname) + " - Marlems PQTTexteditor")
            self.statusBar().showMessage(programmeinstellungen.pfadgeoeffnetedatei)
Bekomme ich folgende Fehlermeldung:
QMainWindowLayout::addItem: Please use the public QMainWindow API instead
Traceback (most recent call last):
File "C:/Projekte/Python/PQT-Texteditor/PQTTexteditor.py", line 39, in menuoffnen
dateininhalt = ''.join(open(dateiname, encoding="utf8").readlines())
File "C:\ProgramData\Anaconda3\lib\codecs.py", line 322, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf6 in position 1: invalid start byte
Ohne encoding:

Code: Alles auswählen

        def menuoffnen():
            dateiname = QFileDialog.getOpenFileName(self, 'Datei öffnen', '', 'Textdateien (*.txt)')
            dateiname = os.path.abspath(dateiname[0])
            programmeinstellungen.pfadgeoeffnetedatei = dateiname
            dateininhalt = ''.join(open(dateiname).readlines())
            self.texteditor.setPlainText(dateininhalt)
            self.setWindowTitle(os.path.basename(dateiname) + " - Marlems PQTTexteditor")
            self.statusBar().showMessage(programmeinstellungen.pfadgeoeffnetedatei)
Bekomme ich keine Fehlermeldung.

Was soll ich tun?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Dann ist der Text in der Datei nicht UTF8 kodiert, und Du mußt das richtige Encoding angeben.
Kein Encoding anzugeben, kann eben nur zufällig richtig sein. Heutzutage sollte man aber kein anderes Encoding als utf8 mehr benutzen.
getOpenFileName liefert keinen Dateinamen, das ist falsch, daher auch das Tupleunpacking:

Code: Alles auswählen

dateiname, _ = QFileDialog.getOpenFileName(self, 'Datei öffnen', '', 'Textdateien (*.txt)')
Und wie oft soll man hier noch schreiben, dass das readlines mit join kompletter Unfug ist und dass man Dateien mit dem with-Statement öffnet, damit sie auch wieder geschlossen werden.

Code: Alles auswählen

with open(dateiname, encoding="DAS RICHTIGE ENCODING") as input:
    dateiinhalt = input.read()
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Und wenn man die richtige Kodierung nicht kennt, weil der Benutzer mit einem allgemeinen Texteditor ja beliebige Daten öffnen kann, sogar welche die gar keine Textdateien sind, muss das Programm grundsätzlich mit dieser Situation umgehen können. Also beispielsweise den Benutzer fragen in welcher Kodierung die Datei geöffnet werden soll. Und dann muss man sich die Kodierung auch grundsätzlich merken, denn wenn der Text wieder gespeichert werden soll, braucht man die ja wieder.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
PythonMarlem
User
Beiträge: 90
Registriert: Dienstag 19. Mai 2020, 19:17
Wohnort: Dußlingen
Kontaktdaten:

Hallo,

zunächst mal als Antwort warum ich nicht das mache, was ihr schreibt:
Weil nach euren Theoretischen Vorschlägen mein Programm nicht mehr funktioniert!
Ich habe jetzt die Funktion als Testfunktion übernommen:

Code: Alles auswählen

        def menuoffnentest():
            dateiname, _ = QFileDialog.getOpenFileName(self, 'Datei öffnen', '', 'Textdateien (*.txt)')
            dateiname = os.path.abspath(dateiname[0])
            programmeinstellungen.pfadgeoeffnetedatei = dateiname
            with open(dateiname, encoding="utf8") as input:
                dateiinhalt = input.read()
            self.texteditor.setPlainText(dateininhalt)
            self.setWindowTitle(os.path.basename(dateiname) + " - Marlems PQTTexteditor")
            self.statusBar().showMessage(programmeinstellungen.pfadgeoeffnetedatei)
mit dem Ergebnis dass das komplette Programm abstürzt mit Fehlercode:
Process finished with exit code -1073740791 (0xC0000409)
Was jetzt?
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@PythonMarlem: Das sieht nach einem harten Absturz aus. Wenn man danach im Netz sucht gibt es einige Treffer die behaupten der Treiber für eine NVIDIA-Grafikkarte wäre schuld und es gibt wohl auch Leute die das gefixt haben.

Ansonsten kann da eine kaputte Installation, ein Bug in einer in C/C++ geschriebenen Erweiterung (Qt oder PyQt beispielsweise), oder die falsche Verwendung von Qt/PyQt die Ursache sein.

Drei Sachen sind hier offensichtlich auch abgesehen von dem Fehlercode falsch: a) Das nur der erste Buchstabe vom Dateinamen verwendet wird, b) das selbst das nicht funktioniert wenn der Benutzer den Dialog abbricht ohne eine Datei auszuwählen, und c) wird das natürlich immer noch nicht mit Texten funktionieren die nicht UTF-8 kodiert sind.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
PythonMarlem
User
Beiträge: 90
Registriert: Dienstag 19. Mai 2020, 19:17
Wohnort: Dußlingen
Kontaktdaten:

Auf Stackoverflow hat man mir geraten zur Fehleranalyse das Programm im Dosfenster auszuführen, weil man dort detaillierte Fehlermeldungen bekommt! Wenn ich das mache, bekomme ich folgendes:
QMainWindowLayout::addItem: Please use the public QMainWindow API instead
Traceback (most recent call last):
File "C:/Projekte/Python/PQT-Texteditor/PQTTexteditor.py", line 48, in menuoffnentest
with open(dateiname, encoding="utf8") as input:
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\Markus Lemcke\\C'
Also um Treiber und Grafikkarten geht es hier nicht.

Idee:
Fehlerbehandlung! Wie kann ich ein falsches encoding mit Fehlerbehandlung abfangen?
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Programm immer in der Kommandozeile ausführen. Wo hast du das denn vorher gemacht? Denn offensichtlich kam die Fehlermeldung gar nicht von deinem Programm.

Der Fehler, den du jetzt bekommst, ist ja recht eindeutig und hat nichts mit der Codierung zu tun. Die Datei, die du öffnen willst, gibt es schlicht nicht.

Und wenn du danach fragst, wie man Exceptions abfängt, sei dir das Python Tutorial ans Herz gelegt. Dort werden alle Grundlagen, auch die Fehlerbehandlung, gut erklärt.
PythonMarlem
User
Beiträge: 90
Registriert: Dienstag 19. Mai 2020, 19:17
Wohnort: Dußlingen
Kontaktdaten:

Um das Encoding-Problem zu lösen, habe ich das hier versucht:

Code: Alles auswählen

 # Encoding Textdateien
        def encodingtextfiles(dateiname):
            encodings = ['utf8', 'windows-1250', 'windows-1252','ANSI']
            for e in encodings:
                try:
                    fh = codecs.open(dateiname, 'r', encoding=e)
                    fh.readlines()
                    fh.seek(0)
                except UnicodeDecodeError:
                    return ('fehler')
                else:
                    return (e)
                    break

Dann hier eingebaut:

Code: Alles auswählen

        def menuoffnenencoding():
            dateiname = QFileDialog.getOpenFileName(self, 'Datei öffnen', '', 'Textdateien (*.txt)')
            dateiname = os.path.abspath(dateiname[0])
            encodingtextf = encodingtextfiles(dateiname)
            if encodingtextf == 'fehler':
                dateininhalt = ''.join(open(dateiname, encoding='utf8').readlines())
            else:
                dateininhalt = ''.join(open(dateiname, encoding=encodingtextf).readlines())
            self.texteditor.setPlainText(dateininhalt)
            self.setWindowTitle(os.path.basename(dateiname) + " - Marlems PQTTexteditor")
Bei manchen Textdateien funktioniert.

Bei einer kommt diese Fehlermeldung:
QMainWindowLayout::addItem: Please use the public QMainWindow API instead
oder diese Fehlermeldung:

Code: Alles auswählen

QMainWindowLayout::addItem: Please use the public QMainWindow API instead
Traceback (most recent call last):
  File "C:/Projekte/Python/PQT-Texteditor/PQTTexteditor.py", line 51, in menuoffnenencoding
    dateininhalt = ''.join(open(dateiname, encoding='utf8').readlines())
  File "C:\ProgramData\Anaconda3\lib\codecs.py", line 322, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfc in position 467: invalid start byte
es ist noch immer nicht die gewünschte optimallösung
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Dass etwas ohne Fehler dekodiert wird, bedeutet nicht, dass es richtig dekodiert wird. Hier wieder die unsinnige Benutzung von readlines, wo read passend wäre.
Dateien die man öffnet sollte man auch wieder schließen. Das seek ist auch überflüssig. Da sowohl im except-Fall als auch wenn es klappt die Funktion per `return` zurückkehrt, ist die for-Schleife überflüssig, der Rückgabewert im Fehlerfall aber nicht zu gebrauchen. Den behandelst Du auch falsch. Ein `break` nach einem `return` ist unsinnig.
Aber ich glaube, ich schreibe hier eh gegen eine Wand. Statt systematisch meine Lösungen durchzuarbeiten und die Fehler in Deiner Lösung zu suchen, rätst Du sowieso nur wild herum.
PythonMarlem
User
Beiträge: 90
Registriert: Dienstag 19. Mai 2020, 19:17
Wohnort: Dußlingen
Kontaktdaten:

Also, ich melde mich jetzt in eurem forum ab, weil egal was man macht ihr schreibt nur Unsinn!
es ist ganz einfach so, Lösungscode bekommt man von euch nie, sondern nur Google-Anweisungen.
Wenn ich dann Lösungscode auf https://stackoverflow.com finde und den dann anpasse, ist euer kommentar:
Wir haben zwar nicht gewußt wie es geht, aber die auf stackoverflow machen alles falsch!

Leute ich habe jetzt keine Lust mehr.
Tschüß!
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Du hast eine komische Realitätswahrnehmung. Den Code von Sirius3 ignorierst Du konsequent und behauptest jetzt auch noch Du würdest hier nie Code bekommen.

Aber hey, Du bist ja anscheinend Software-Entwickler und hast schon barrierefreie Texteditoren in C# und Java implementiert und trotzdem sieht das hier mehr nach raten als nach programmieren aus. Nach zwei Texteditoren scheint das Thema Textkodierung auch komplett neu für Dich zu sein.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten