Eingaben abfangen

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
halux
User
Beiträge: 11
Registriert: Samstag 28. März 2009, 17:06
Wohnort: Liesten

Hallo,

ich möchte Eingaben, die durch QLineEdit eingegeben werden abfangen
und zum rechnen aufarbeiten.

z.B. sollen Buchstaben entfernt und Kommatas durch Punkte ersetzt werden.

Habe leider keinen Plan wie ich das anstellen kann.

Anbei mein Beispiel

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: cp1252 -*-


import sys
from PyQt4 import QtGui
from PyQt4 import QtCore


class Hauptfenster(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self)
        #self.setGeometry(300, 150, 640, 700)
        self.setWindowTitle(u'abfangen und auswerten von Eingaben')
        self.initial()

    def ggf_breite_anzeigen(self):
        print self.bst_art.currentText()
        negativliste = ('R-188 A','HEB-180','Q-257')
        if self.bst_art.currentText() in negativliste :
            self.breite.setEnabled(False)
        else:
            self.breite.setEnabled(True)

    def eingabe_richten(self,value):
        """ Abfragen ob nur Zeichnen zum rechnen ??
            ggf. andere zeichen entfernen und komma durch punkte ersetzen """

    def speichern(self):
        print self.bst_art.currentText()
        print self.laenge.text()
        print self.breite.text()
        

    def initial(self):
        self.l_1 = QtGui.QLabel(u'Durchmesser :')
        self.l_2 = QtGui.QLabel(u'Länge/Abwicklung :')
        self.l_3 = QtGui.QLabel(u'Breite/Abwicklung :')
        
        self.bst_art = QtGui.QComboBox()
        bst_liste =('6','8','10','12','14','R-188 A','HEB-180','Q-257')
        for eintrag in bst_liste:
            self.bst_art.addItem(eintrag)
        self.connect(self.bst_art, QtCore.SIGNAL('currentIndexChanged(int)'),self.ggf_breite_anzeigen)
               
        self.laenge = QtGui.QLineEdit()
        self.connect(self.laenge, QtCore.SIGNAL('currentTextChanged(int)'),self.eingabe_richten)
        self.breite = QtGui.QLineEdit()
        self.speichern_btn = QtGui.QPushButton(u"Position speichern")
        #self.speichern_btn.setEnabled(False)
        self.connect(self.speichern_btn, QtCore.SIGNAL('clicked()'), self.speichern)

        self.grid = QtGui.QGridLayout()
        self.grid.addWidget(self.l_1,0,0)
        self.grid.addWidget(self.bst_art,0,1)
        
        self.grid.addWidget(self.l_2,1,0)
        self.grid.addWidget(self.laenge,1,1)
        
        self.grid.addWidget(self.l_3,2,0)
        self.grid.addWidget(self.breite,2,1)

        self.grid.addWidget(self.speichern_btn,3,1)

        self.setLayout(self.grid)

        

app = QtGui.QApplication(sys.argv)
programm = Hauptfenster()
programm.show()
sys.exit(app.exec_())
lunar

Eine gut-geschriebene GUI sollte nicht auf magische Weise am eingegebenen Text herummanipulieren. Das ist für den Nutzer weder intuitiv noch verständlich. Stattdessen validiert eine GUI lediglich die Eingabe und zeigt im Falle einer ungültigen Eingabe ein Fehlermeldung.

Qt4 bietet dafür bereits fertige Klassen, nämlich QDoubleValidator (Beispiel).

Im Übrigen solltest du darauf achten, dass Code und Frage zusammen passen. Dein Code betrifft eine QComboBox, deine Frage aber dreht sich um ein QLineEdit. Hilfreich ist diese Diskrepanz nicht ;)

Deine Namensgebung ist übrigens sehr komisch ... Namen wie "1_1" sind nicht gerade informativ, mal abgesehen davon, dass du für die Label gar keine Namen benötigst. Es reicht, wenn du sie anonym erzeugst:

Code: Alles auswählen

self.grid.addWidget(QtGui.QLabel(u'Durchmesser:', self), 0, 0)
Außerdem solltest du darauf achten, dass du bei jedem Widget das Vaterobjekt korrekt setzt, sonst kann es mitunter zu unerwarteten Ergebnissen kommen, wenn der Python-GC Objekte löscht und Qt keine Referenz mehr auf diese Objekte hält.
halux
User
Beiträge: 11
Registriert: Samstag 28. März 2009, 17:06
Wohnort: Liesten

Hallo lunar,

. . . soweit so gut, Tipps wurden angenommen :wink:
aber , warum soll ich nicht Kommatas automatisch in Punte umwandeln lassen, da
1. ich mit eval() die Eingabe gleich zusammenrechnen lassen möchte.
2. die Eingabe der Zahlen erfolgt über die Nummerntastatur, und da steht nun mal ein Komma, was automatisch zu Fehleingaben führt !

Evtl. klappt die Umwandlung ( Prüfung ) auch mit dem QRegExpValidator ??
Weil, es gibt doch für Zahlen und mathematische Zeichen einen
entsprechenden reg.Ausdruck, gegen den verglichen werden kann.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

halux hat geschrieben:[...]warum soll ich nicht Kommatas automatisch in Punte umwandeln lassen[...]
Das ist "magisches" Verhalten und dürfte nach jeden Interface Guidelines ein absolutes no-go sein.
1. ich mit eval() die Eingabe gleich zusammenrechnen lassen möchte.
Sehr sehr schlechte Idee.
2. die Eingabe der Zahlen erfolgt über die Nummerntastatur, und da steht nun mal ein Komma, was automatisch zu Fehleingaben führt !
Davon muss der User nichts mitbekommen.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

halux hat geschrieben:1. ich mit eval() die Eingabe gleich zusammenrechnen lassen möchte.
Sehr schlecht. Der User kann dann beliebige Befehle eingeben, die direkt ausgeführt werden.
halux hat geschrieben:2. die Eingabe der Zahlen erfolgt über die Nummerntastatur, und da steht nun mal ein Komma, was automatisch zu Fehleingaben führt !
Dann wandel das Komma halt intern in einen Punkt um.
lunar

halux hat geschrieben:warum soll ich nicht Kommatas automatisch in Punkte umwandeln lassen
Es ist allgemein bekannt, dass Punkte innerhalb von Zahlen im deutschen Sprachraum für das Tausendertrennzeichen stehen, Kommata (sic!) dagegen für das Dezimaltrennzeichen. Die Zahl "1.125" hat daher eine völlig andere Bedeutung als die Zahl "1,125". Für den Benutzer wäre das Ersetzen der Kommata durch Punkte folglich keine Korrektur, sondern vielmehr eine Verfälschung der Eingabe. Neben der daraus resultierende Verwirrung versucht der Nutzer womöglich noch, die scheinbar falsche Zahl zu korrigieren, was natürlich nicht funktioniert.

Eine solche GUI ist alles andere als intuitiv und für den Benutzer schwer verständlich. Die automatische Manipulation von Eingaben ist zwar an sich akzeptabel, wenn es z.B. um Aufbereitung der Daten geht. Allerdings darf sie den sichtbaren Wert nicht verändern. Für das Programm mag "1.125" und "1,125" das Gleiche sein, für den Benutzer sind das zwei unterschiedliche Zahlen!

Lass ab von der Idee, "eval()" zu verwenden. Das Sicherheitsrisiko ist bei einer lokalen Anwendung zwar zu vernachlässigen, aber die Fehlerbehandlung ist suboptimal. Vergisst der Benutzer bei der Eingabe beispielsweise den rechten Operanden, so sieht er sich mit der für normale Nutzer kryptischen und unverständlichen Fehlermeldung "unexpected EOF while parsing" konfrontiert. Um arithmetische Ausdrücke zu übersetzen und auszuwerten, solltest du einen eigenen Parser ala pyparsing nutzen. Bei pyparsing ist ein einfacher Parser für solche Ausdrücke in den Beispielen enthalten.

Allerdings kannst du dann QDoubleValidator nicht mehr nutzen, da dieser nur Zahlen, aber keine Ausdrücke erkennt. QRegExpValidator funktioniert ebenfalls nicht, da man geschachtelte und geklammerte Ausdrücke schlecht bis gar nicht als regulären Ausdruck modellieren kann. Allerdings kannst du eine eigene Klasse von QValidator ableiten und deinen Parser zur Validierung nutzen.
halux
User
Beiträge: 11
Registriert: Samstag 28. März 2009, 17:06
Wohnort: Liesten

OK, OK habe verstanden.
Die Eingaben so akzeptieren, nur bei groben Fehleingaben, wie z. B. Buchstaben diese Fehleingaben anzeigen, und ansonsten intern die Umwandlungen wie gewünscht vornehmen.
Also muß ich die Eingaben parsen.
Das wird nach meinem Urlaub das nächtste sein. Dabei auftretende Fragen stell ich dann wieder hier hinein !

halux
Antworten