Datenausgabe in einem Text Browser Fenster

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
sonstwas
User
Beiträge: 2
Registriert: Montag 24. Oktober 2011, 10:52

Hi,

ich bin dabei ein Programm mit Grafikoberfläche zu schreiben um einen Sensor über PySerial auszulesen. Das klappt soweit auch alles, sobald ich den Start Button drücke.
Das Problem ist jetzt, dass ich die Daten in einem Textbrowser Fenster ausgeben will, was auch klappt. Jedoch erst nachdem ich die Schleife, in der die Daten ausgelesen werden, beendet habe. Gibt es eine Möglichkeit, dass die Daten direkt in dem Textbrowser Fenster anzeigt werden ?

Gruß

hier die Schleife

Code: Alles auswählen

 while 1:
            try:
                sen.write(chr(0xf7) + chr(0x07)+ chr(0x07))
                binaryData = sen.read(12)
                Angle = ""
                Orientation = struct.unpack(">fff", binaryData)
                Roll = Orientation[0] *180 / math.pi
                Yaw = Orientation[1] * 180 / math.pi
                Pitch = Orientation[2] *180 / math.pi
                Angle = Angle + str(Roll) + " " + str(Yaw) + " " + str(Pitch)
                self.textBrowser.append(Angle)  
            except KeyboardInterrupt:
                break
        sen.close()
Zuletzt geändert von Anonymous am Montag 24. Oktober 2011, 13:13, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@sonstwas: Wenn Du parallel etwas zur GUI machen willst, dann musst Du das über Timer oder Threads tun und darauf achten, dass Du auf die GUI nur aus dem Hauptthread zugreifen darfst. Was in Qt aus jedem Thread erlaubt ist, wäre das versenden von Signalen. Du könntest Dir also ein eigenes Signal basteln was die Ergebnisse von den Abfragen sendet.
BlackJack

@sonstwas: Noch ein paar Anmerkungen zum Quelltext: Python hat einen eigenen Typ für Wahrheitswerte, den sollte man verwenden wenn man Wahr und Falsch sagen will. Statt Zahlen dafür zu missbrauchen.

Dein Einsatz von `chr()` und ``+`` um Zeichenketten zusammen zu basteln sieht irgendwie nach BASIC aus. In Python würde man die Hexwerte eher direkt als Escapesequenz in eine Zeichenkette schreiben und Zeichenkettenformatierung mittels ``%``-Operator oder `format()`-Methode auf Zeichenketten verwenden.

Die Namenskonvention bei Python ist `klein_mit_unterstrichen`. Namen die mit Grossbuchstaben beginnen sind für Klassen reserviert. Ausserdem sollte man auf Abkürzungen verzichten. Was ist `sen`?

Namen zwischendurch mal an Daten zu binden, die dann doch nirgends verwendet werden, sollte man sich sparen (``Angle = ""``).

Für die Umrechnung zwischen Grad und Bogenmass gibt es in `math` fertige Funktionen: `degrees()` und `radians()`.

`KeyboardInterrupt` in einer GUI-Anwendung zum Abbrechen einer Schleife ist vielleicht nicht so günstig. Hier würde ich statt einer Endlosschleife vielleicht eher eine mit Abbruchbedingung machen. Vielleicht mit einem Slot auf dem Objekt zum Anhalten/Abbrechen.

Ungetestet:

Code: Alles auswählen

        try:
            while True:
                sen.write('\xf7\x07\x07')
                orientation = struct.unpack('>fff', sen.read(12))
                roll, yaw, pitch = map(math.degrees, orientation)
                self.textBrowser.append('%s %s %s' % (roll, yaw, pitch))
                # oder auch als Signal:
                self.orientationRead.emit(roll, yaw, pitch)
        except KeyboardInterrupt:
            pass
        finally:
            sen.close()
sonstwas
User
Beiträge: 2
Registriert: Montag 24. Oktober 2011, 10:52

Hi BlackJack,

danke für die Info und die Hinweise :)
Der KeyboardInterrupt ist nur vorläufig da, der wird noch durch einen Stop Button ersetzt.

Gruß
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Ja, das mit einer `while True`-Schleife mit KeyboardInterrupt zu machen, ist sicher nicht das gewünschte Verhalten. Problem ist, dass Deine GUI "hängt" während das Programm in der Schleife verweilt und erst wieder nach Ctrl-C reagiert.

Besser wäre es, das Schreiben nach `sen` über ein Signal Deiner Qt-Klasse mitzuteilen und das Lesen über eine gesonderte Methode zu triggern (evtl. mit Timer, falls Dein Sensor Zeit braucht, die Antwort zu generieren). Das wiederholte Schreiben könntest Du ebenfalls über einen QTimer realisieren.

Ein anderer gangbarer Weg wäre, Deinen Code in einen eigenen Thread zu packen, `while True` durch eine vom Hauptthread aus setzbare Bedingung zu ersetzen (dadurch erhältst Du die Möglichkeit, den Thread bei Bedarf zu beenden) und die gelesenen Daten über ein Signal zum Hauptthread zu schicken. `self.textBrowser.append()` sollte nicht vom Nebenthread aufgerufen werden.
Antworten