Weg mit den Leerzeichen

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hallo Leute,

folgende Situation: Bevor Daten aus den Textfelder verarbeitet werden, will ich noch einige Überprüfungen unternehmen. Eine davon ist zu prüfen, ob der Anwender überhaupt etwas in den Textfelder geschrieben hat, und nicht in der lineEdit nur die Leertaste und in der textEdit nur die Enter-Taste betätigt hat.

Für die Überprüfung bin ich wie folgt vorgegangen:

Code: Alles auswählen

    
    def check_inputs(self):
        self.str_lineEditSubject = str(self.ui_pp_feedback.lineEditSubject.text())
        self.str_textEditFeedback = self.ui_pp_feedback.textEditFeedback.toPlainText

        if not len(self.str_lineEditSubject.strip()) == 0:
            print "not blank string"
            if  len(self.str_textEditFeedback .strip()) == 0:
                print "not blank string"
            else:
                print "str_textEditFeedback: blank string"
                self.ui_pp_feedback.textEditFeedback.textBackgroundColor ('#f6989d;') # red
                self.show_msgbox_error()
        else:
            print "blank string"
            self.ui_pp_feedback.lineEditSubject.setStyleSheet('background-color: #f6989d;') #red
            self.show_msgbox_error()
In Zeile 1-2 wandel ich den Inhalt der Textfelder erst einmal in einem String um. Der Grund, warum ich sie umwandel, ist, das ich später mit der strip-Methode arbeiten kann. Anschließend kommt von Zeile 6-16 ein großer If-Else-Block. Dieser Block prüft erst einmal das str_lineEditSubject-Textfeld, ob da nur Leerzeichen vorhanden sind. Das tue ich mit der strip-Methode. War die Prüfung in diesem Textfeld erfolg, also dort sind nicht NUR Leerzeichen vorhanden, dann soll das nächste Textfeld überprüft werden, und zwar textEditFeedback.

Und jetzt bekomme ich zwei Probleme. Im textEditFeedback greift die strip-Methode nicht. Folgende Fehlermeldung:
AttributeError: 'builtin_function_or_method' object has no attribute 'strip'
Ich kann mir vorstellen warum, eben weil dieses Textfeld im Gegensatz zu der lineEdit MultiLines zulässt? Jedoch weiß ich leider nicht, wie ich das Problem lösen soll. Zudem gleich eine Frage hinten ran. Geht mein Vorgehen auch etwas eleganter und weniger so verwirrend aussehend? Denn bei mehreren Textfeldern wird es kritisch.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Schau Dir mal Zeile 4 *genau* an! Wenn Du dann nicht drauf kommst, lass Dir mal den Typen von ``str_textEditFeedback`` ausgeben ;-)

Ach ja: ``isspace()`` könnte was für Dich sein :-)

Außerdem wirst Du bei dieser Art Code ja rammdösig, wenn Du noch sagen wir mal 5 - 100 weitere Textfelder einbaust, die überprüft werden sollen! Das musst Du dringend verallgemeinern und mittels Schleife lösen, die eine gegebene Vorgabe für ein gegebenes Element prüft und dann eine Aktion auslöst.

Last but not least: Wieso nutzt Du hier die verpönte ungarische Notation für Deine Namen? :evil:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@Hyperion: Danke für den Hinweis auf Zeile 4. Aber dennoch hat es nicht weit gebracht. Die Überprüfung klappt immer noch nicht. Zu deiner Frage, warum ich diese verpönte ungarische Notation benutze. Einfach, weil ich hier mit String arbeite, da wollte ich es leserlich machen. Das heiß, der Wert in diesem Attribut ist ja nun ein String.

Und das mit der Schleife habe ich mir fast gedacht. Da muss ich mich mal ransetzen. Klingt nur etwas schwierig, da ich rein vom Gedankengang Probleme habe dies umzusetzen. Wir gehen davon aus, dass die Textfelder unterschiedliche Namen haben, am Ende 100 davon gibt. Ich müsste jedes Textfeld einmal durch die For-Schleife jagen? Richtig? Klingt aber genauso rammdösig :-)
Benutzeravatar
pillmuncher
User
Beiträge: 1490
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Was Hyperion gesagt hat.

Noch zur Ungarischen Notation: Charles Simonyi hat die bei Microsoft erfunden. Seine Kollegen haben aber anscheinend seinen Artikel nicht wirklich gelesen, denn sie haben daraus etwas grauenhaftes gemacht, was dort gar nicht drinstand. Wer Ungarische Notation wirklich anwenden will, sollte zuerst den Artikel lesen und sich dann überlegen, ob er überhaupt ein zur darin genannten Lösung passendes Problem hat. Andernfalls bitte nicht verwenden. Und bitte auch hier den Punkt 30 lesen.

Wenn man testen will, ob ein String leer ist, dann macht man das in Python nicht, indem man nachschaut, ob er eine Läne von Null hat. Man kann ihn gleich gegen "" vergleichen, oder, am besten, man vergleicht ihn gar nicht, sondern testet so:

Code: Alles auswählen

if some_string:
    irgendwas()
Denn bool(some_string) ist nur dann falsch, wenn der some_string leer ist. Und ja, das ist die in PEP8 favorisierte Variante.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@pillmuncher: Deine Anmerkung war mir geläufig, jedoch habe ich sie nicht angewendet, weil sie bei einem textEdit-Widget offenbar nicht greift. Ich habe dir nochmal den Code reinkopiert, und zwar mit deiner Anmerkung. Ohne Erfolg.

Code: Alles auswählen

    def check_inputs(self):
        self.str_lineEditSubject = str(self.ui_pp_feedback.lineEditSubject.text())
        self.str_textEditFeedback = str(self.ui_pp_feedback.textEditFeedback.toPlainText)

        #if not self.my_string.strip() == '':
        if not len(self.str_lineEditSubject.strip()) == 0:
        #    print "not blank string"
            if self.str_textEditFeedback:
                print "not blank string"
            else:
                print "str_textEditFeedback: blank string"
                self.ui_pp_feedback.textEditFeedback.setStyleSheet('background-color: #f6989d;') # red
                self.show_msgbox_error()
        else:
            print "blank string"
            self.ui_pp_feedback.lineEditSubject.setStyleSheet('background-color: #f6989d;') #red
            self.show_msgbox_error()
BlackJack

@Sophus: Ergänzend zu den bisherigen Fragen: Warum bindest Du die (vermeintlichen) Zeichenketten an das Objekt? Das macht keinen Sinn.

Ab einer gewissen Anzahl von Eingabefeldern wird man das wohl in Daten auslagern aus denen dan sowohl die UI erstellt wird und die vom generischen Code zur Überprüfung von Einschränkungen herangezogen wird.

Was hat denn das nähere Betrachten von Zeile 4 an Erkenntnis gebracht. Der Ausdruck rechts vom ``=`` ergibt keine Zeichenkette. Was ist es denn? Und warum? Und wenn Du den Fehler korrigierst stimmt entweder die falsch verstandene ungarische Notation beim Namen nicht, oder der `str()`-Aufruf in der Zeile davor war unnötig. Ausserdem solltest Du mal einen Umlaut in die Betreffzeile schreiben und testen ob das immer noch funktioniert. Je nach Python-Version ist `str()` an der Stelle nämlich die falsche Funktion.

Wenn Du das mit den farbig hinterlegten Eingabefeldern bei Fehlerhaften Angaben echt überall durchziehen willst, dann solltest Du da auch eine generische und wiederverwendbare Lösung programmieren und das nicht dauernd überall immer wieder hinschreiben müssen.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@Ihr: Erst einmal Schritt für Schritt :-)

Wenn man eine erhebliche Anzahl an TextFelder hat, sollte man es vereinfachen. Das waren eure Worte. Auch verständlich. Im Sinne von Textfelder löschen habe ich folgendes gebastelt:

Code: Alles auswählen

    def clear_all_inputs(self):

        editFields = [self.ui_pp_feedback.lineEditSubject,
                           self.ui_pp_feedback.textEditFeedback]
        
        for field in editFields:
            field.clear()
Hier werden alle Textfelder in einer List Comprehensions eingetragen. Und dann jage ich anschließend diese Liste (editFields) durch die For-Schleife, damit alle dort eingetragene Textfelder (Elemente) geleert werden. Klappt auch alles. Nun aber muss ich mir was einfallen lassen, wie ich dieses Schema so anwenden kann, dass ich in der For-Schleife nach Leerzeichen untersuchen kann, also nach leeren Textfeldern. Eine If-Else-Schleife in einer For-Schleife beißt sich, oder?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Sophus hat geschrieben:Hier werden alle Textfelder in einer List Comprehensions eingetragen.
Das ist keine LC das ist eine Liste. Ein LC hat die Form

Code: Alles auswählen

[x for x in ...]
Sophus hat geschrieben:Eine If-Else-Schleife in einer For-Schleife beißt sich, oder?
Mal abgesehen hiervon, da gibt es gar kein Problem. Es ist ganz normal, dass dass Konstrukte verschachtelt werden. Wenn es zu tief oder zu lang wird, dann bieten sich Funktionen an. Oder mir ist einfach nicht ganz klar, was du mit der Aussage meinst.
Das Leben ist wie ein Tennisball.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@EyDu: Ich dachte, es wäre in Python üblich, dass man in einer For-Schleife auf die If-Else-Schleife verzichtet.

Ich habe das wie folgt gelöst (funktioniert):

Code: Alles auswählen

    def check_all_inputs(self):
        editFields = [str(self.ui_pp_feedback.lineEditSubject.text()),
                           str(self.ui_pp_feedback.textEditFeedback.toPlainText())]

        for field in editFields:
            if field.strip() == '':
                self.show_msgbox_error()
Es scheint auch zu klappen. In meiner Python-Version (2.7.6) muss ich immer str() bei den Textfeldern benutzen. Es klappt anscheint auch alles. Jetzt muss ich irgendwie dahinter kommen, wie ich an die Textfelder rankomme, die leer sind. Also das richtige Textfeld finden, damit ich das Textfeld dann entsprechend rot färben kann, damit der Anwender sieht, wo noch was nicht korrekt eingegeben wurde. Bei zwei Textfeldern ist es ja noch übersichtlich, aber mir geht es erst einmal ums Verständnis. Man will ja was lernen :-)
BlackJack

@Sophus: Du hast also anscheinend noch nicht versucht wie von mir vorgeschlagen mal einen Umlaut einzugeben. Dann wäre Dir aufgefallen das `str()` nicht die richtige Funktion ist.

Und bei der Schleife würde die Fehlermeldung bei *jedem* leeren Feld kommen. Falls das ein Fenster ist was man wegklicken muss wird der Benutzer wahrscheinlich irgendwann sehr genervt sein. :-)
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@BlackJack: Eins nach dem anderen :-)

Die Umlaute. Du hast Recht, wenn ich die Umlaute verwende, und anschließend auf den Button klicke, bekomme ich folgende Fehlermeldung:

Code: Alles auswählen

UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 0: ordinal not in range(128)
In vielen Fällen, in welcher man in den Variablen einen Text festlegt, schreibt man ja ein u davor. Etwa so var = u"Python ist schön". Aber wie verhält es sich hierbei? Lasse ich aber die str()-Methode(?) weg, dann kann ich im nachfolgenden Code die strip()-Methode nicht verwenden. Ein Teufelskreis.

Nun, ich musste selber lachen, als ich feststellte, dass bei meiner vorherigen For-Schleife bei jedem leeren Element eine Msg-Box angezeigt wurde. Man stelle sich vor, es wären 100 Texfelder, alle wären leer. Der arme Anwender. Er kann schon mal seine Kaffeemaschine anmachen :-D
Also habe ich es wie folgt gelöst, nur fehlt mir ein kleiner Schritt. Aber alles zu seiner Zeit. Hier mein Code:

Code: Alles auswählen

    def check_inputs(self):
        editFields = [str(self.ui_pp_feedback.lineEditSubject.text()),
                           str(self.ui_pp_feedback.textEditFeedback.toPlainText())]

        print len(editFields)

        for i in range(len(editFields)):

            print i, editFields[i]

            if editFields[i].strip() == '':
                if not len(editFields) <= i:
                    print "element %s empty" % i
                    self.show_msgbox_error()
                else:
                    print "not empty"
                break
Nun, ich habe zu meiner vorigen For-Schleife eine range()-Funktion hinzugeholt. Damit wollte ich die For-Schleife für die Iteration nutzen. Ansonsten ist bis Zeile 9 eigentlich alles geblieben. Ab Zeile 10 wollte ich prüfen, ob Listen-Element bei Index i gesetzt ist oder nicht. Sprich, ich will herausfinden, welches Element in der Liste nun Leer ist. Nach der Überprüfung lass ich es mir in Zeile 11 per print-Befehl auch anzeigen. Hier arbeite ich mit dem Platzhalter %s im String und % außerhalb des Strings. Und in Zeile 15 setze ich einen Break, damit der Benutzer nicht ewig auf die MessageBox klicken muss, wenn ich zum Beispiel 100 Stück davon verwende :-)

Nun ist mein Anliegen zweierlei: Wie bekomme ich das mit der Fehlermeldung behoben? Irgendwie muss ich ständig etwas decodieren und dann encodieren? Und dann die nächste Frage: Wie komme ich an das entsprechende Element heran, dass auch das entsprechende Textfeld auch farbig markiert werden kann. In meinem Beispiel sind momentan zwei Textfelder, also sieht die Zählung in der Liste wie folgt aus 0 für Textfeld1 und 1 für Textfeld. Jetzt könnte ich mit der If-Kaskade nachfragen, welches Element nun leer ist, und entsprechend reagieren. Aber das wäre genauso unsinnig. Jemand eine Idee?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Sophus hat geschrieben:In vielen Fällen, in welcher man in den Variablen einen Text festlegt, schreibt man ja ein u davor. Etwa so var = u"Python ist schön". Aber wie verhält es sich hierbei?
Was könnte das u vor Strings nur bedeuten? Wenn man das wüsste, dann wäre man der Lösung des Problems schon ganz dicht auf den Fersen ;-)
Sophus hat geschrieben:

Code: Alles auswählen

for i in range(len(editFields)):
Warum hast du deinen Code jetzt so verunstaltet? Bei deinen vielen Beiträgen wurdest du bestimmt schon darauf hingewiesen, dass das ein absolutes Antipattern ist. Du bist doch vorher auch direkt über die Liste iteriert. Wenn du einen Index benötigst, dann benutze die enumerate-Funktion.
Sophus hat geschrieben:

Code: Alles auswählen

if editFields[i].strip() == '':
Darauf wurdest du weiter oben auch schon hingewiesen. Das lässt sich viel einfacher als

Code: Alles auswählen

if not field:
schreiben.
Sophus hat geschrieben:

Code: Alles auswählen

if not len(editFields) <= i:
    print "element %s empty" % i
Da solltest du wirklich noch einmal gründlich drüber nachdenken ob es wirklich das tut, was du denkst.
Sophus hat geschrieben:Hier arbeite ich mit dem Platzhalter %s im String und % außerhalb des Strings.
Die Funktionsweise musst du uns nicht erklären, die ist allen bekannt. Allerdings solltest du besser die format-Methode auf Strings verwenden, Formatierung mittels % ist veraltet.
Sophus hat geschrieben:In meinem Beispiel sind momentan zwei Textfelder, also sieht die Zählung in der Liste wie folgt aus 0 für Textfeld1 und 1 für Textfeld. Jetzt könnte ich mit der If-Kaskade nachfragen, welches Element nun leer ist, und entsprechend reagieren. Aber das wäre genauso unsinnig. Jemand eine Idee?
Indem du nicht die Strings in eine Liste packst, sondern die Widgets. Dann kannst du auch direkt auf die zugreifen. Eventuell musst du die Schnittstelle zu den Widgets noch ein wenig abstrahieren, damit du für verschiedenen Widgets dieselbe Schnittstelle hast.
Das Leben ist wie ein Tennisball.
BlackJack

@Sophus: Du möchtest Dich über den Unterschied zwischen einer Sequenz von Bytewerten (Datentyp `str`) und einer Sequenz von Zeichen (Datentyp `unicode`) schlau machen, und wie das mit Zeichensatzkodierungen zusammenhängt. Und eventuell auch mal mit dem Datentyp den Du da von Qt bekommst, denn der hat zwar keine `strip()`-Methode aber eine `trimmed()`-Methode.

Das mit dem `i` für Indexzugriffe ist in Python ein „anti-pattern”. Man kann ja direkt über Elemente von Listen iterieren ohne diesen Umweg. Und wenn man den Index *zusätzlich* braucht, macht man das mit der `enumerate()`-Funktion. Allerdings denke ich das ist auch keine Lösung denn wenn man dem Benutzer mitteilt das Eingabfeld 16 von 25 leer ist, dann fängt der ja sicher nicht an die Felder abzuzählen. Zumal man ja schon in der Lage ist leere Felder sehr leicht zu erkennen ohne ihre ”Nummer” zu wissen.

Die Logik in der Schleife scheint mir falsch zu sein. ``if not len(editFields) <= i:`` nicht nur sehr verworren ausgedrückt, es ist ja das gleiche wie ``if len(editFields) > i:`` und das ist *immer* wahr. Das ``if``/``else`` macht dort also keinen Sinn. Und man hat deshalb auch immer noch für jedes Feld die Warnungsmeldung.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@EyDu:

Ich habe nun die Widgets in meine Liste gepackt, also nicht als String, und habe dann die einfache Form genommen, ob man überprüfen kann, ob einige Elemente leer sind. Hier der Code:

Code: Alles auswählen

    def check_inputs(self):
        editFields = [self.ui_pp_feedback.lineEditSubject.text(),
                      self.ui_pp_feedback.textEditFeedback.toPlainText()]
        print len(editFields)
        for field in editFields:
            if not field:
                self.show_msgbox_error()
            else:
                print "No error"
            break
Jedoch verhält er sich nicht so wie gewünscht. Wenn ich die Textfelder als mit Leerzeichen fülle und dann auf den Button klicke, dann kommt eher die print-Meldung, dass "no error" vorliegen. Wie es aussieht, ist die einfache Schreibweise nicht immer die beste :-) Daher bin ich bei der strip()-Methode geblieben, und hatte die Widgets als String in die Liste gepackt. Irgendwas mache ich hier falsch.

Ach so. Was ist ein Antipattern? Heißt das soviel wie "Mach das nicht, weil die anderen in deiner Schulklasse das auch nicht machen"? :-) Entschuldige, musste eben sein. Aber jetzt mal im ernst. Was ist da der Nachteil in meinem Code-Beispiel.?
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@BlackJack: Das Thema Zeichensatzkodierung scheint ein verwirrendes Thema zu sein. Da raucht einem ja schon die Birne beim Lesen. Ich glaube, unter Linux hat man solche Probleme gar nicht erst. Wieso das unter Windows so ist, keine Ahnung. Was mich aber noch mehr verwirrt. Wenn ich in Python-Quelltext einer Variable einen Text festlege, kann ich immer ein u vor dem String setzen, so wird in Python ein Unicode-kodierter String erzeugt.
Zum Beispiel:

Code: Alles auswählen

var = u"Schöne neue Welt"
Und so "einfach" ginge das nicht mit einem Textfeld?

Übrigens, dass mit der trimmed()-Methode greift leider nur bedingt. Ein QtextEdit-Widget kennt diese Methode nicht, sondern nur das QlineEdit-Widget.
BlackJack

@Sophus: Du hast da nicht die Widgets in die Liste gepackt, es werden immer noch Zeichenketten, halt von einem anderen Typ, in die Liste gepackt und nicht die Widgets von denen sie abgefragt werden. Und wenn Du Zeichenketten darauf prüfen möchtest ob sie mehr als nur Whitespace-Zeichen enthalten, dann musst Du das halt auch entsprechend überprüfen. Nur halt komplett in der Schleife über Widget-Objekte, also *dort* den Text abfragen, gegebenenfalls in einen anderen Zeichenkettentyp umwandeln und dann zum Beispiel alle Whitespace-Zeichen am Anfang und am Ende entfernen und schauen ob's dann noch Zeichen gibt, was dem Wahrheitswert von Zeichenketten entspricht, und zwar allen drei Typen die wir hier bisher gesehen haben. Die einfachere Schreibweise für zwei Ausdrücke die den gleichen Effekt haben ist in der Regel die bessere. Nur ist es eigentlich recht offensichtlich dass das hier nicht das macht, nicht machen *kann*, wie der Code bei dem man die Whitespace-Zeichen entfernt bevor man den Wahrheitswert der Zeichenkette als Entscheidungskriterium verwendet.

Wenn man (tatsächlich) über die Widget-Objekte iteriert hat man allerdings das Problem das die nicht die gleiche API haben um den Text abzufragen. Und um das sauber objektorientiert zu lösen braucht es IMHO ein bisschen mehr Erfahrung mit den Grundlagen als Du momentan hast. Gefühlt rätsts Du Dich eher durch den Code, die Datentypen, und die API, als das Du tatsächlich verstehst was die einzelnen Teilausdrücke für Werte, Typen, und damit Operationen haben.

Bei der Schleife bin ich zum Beispiel gespannt auf die Antwort was das ``break`` Deiner Meinung nach macht.

Ja, „anti pattern” sind Sachen die man nicht macht. Der Nachteil ist das es komplizierter ist als der Umweg über einen Index, und unflexibler weil der Zugriff über den Index einen Sequenztyp voraussetzt, während direktes Iterieren mit jedem iterierbaren Objekt funktioniert, also auch mit solchen die keinen Indexzugriff bieten. Das `i` ist hier ja auch eigentlich nicht der Index, sondern hauptsächlich hinzugekommen um eine Ausgabe zu erzeugen. Und Benutzer wollen in der Regel keinen Index der bei 0 anfängt, den ”normale” Menschen zählen Dinge ab 1 ab. Was mit `enumerate()` auch einfach möglich ist.

Zeichensatzkodierung ist unter jedem System ein Thema. Da führt kein Weg dran vorbei, das muss man heutzutage als Programmierer verstehen das Thema. Die Zeiten das man sich mit einer Ein-Byte-Pro-Zeichen-Kodierung durchmogeln konnte, also das Thema weitgehend ignorieren weil ”alle” die gleiche Kodierung benutzen, sind schon länger vorbei.

Der u-Präfix ist für literale Unicode-Zeichenketten im Quelltext. GUI-Toolkits machen da in der Regel schon das richtige und können mit Unicode umgehen. *Du* provozierst den Fehler in dem Du versuchst aus Zeichen wieder Bytes zu machen. Ohne eine Kodierung anzugeben. Was jetzt nicht heissen soll das Du eine Kodierung angeben solltest — lass die Zeichen einfach Zeichen bleiben.

*Weder* `QTextEdit`- *noch* `QLineEdit`-Objekte haben eine `trimmed()`-Methode…
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@BlackJack: Das mit den Widgets. Das heißt, man muss da eine Etage höher, und abstrakter arbeiten, damit am Ende auch alle Widgets entsprechend in einer For-Schleife behandelt werden können? Das heißt dann für mich, diese Idee erst einmal beiseite zu legen, und mich andere Gebiete innerhalb des ToolKits anschauen?

Zu deiner gespannten Frage: Also, wie ich break interpretieren würde? Ich sehe das eher wie ein GoTo unter VB6. In meinem Fall wollte ich einfach so vorgehen, dass nach dem ersten Fehler, der gefunden wurde, die For-Schleife unterbrochen wird und nicht bis zum Ende durch gezogen wird. Sonst bekommt der Anwender ja zig Msg-Box-Fenster und klickt sich die Finger wund oder die Maus kaputt :-) Sobald also ein Element in der Liste gefunden wurde, welches leer ist, soll die For-Schleife mit einem break abgebrochen werden. Aber wie ich mir denke, habe ich total falsch verstanden? :-)
BlackJack

@Sophus: Das ``break`` in Deiner letzten Schleife wird bedingungslos am Ende des Schleifenkörpers aufgerufen. Damit läuft diese Schleife nur einmal für das erste Element und niemals für das zweite.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@BlackJack: Das heißt nun was? Der Break muss also innerhalb des Schleifenkörpers in den else-Block? Etwa so?

Code: Alles auswählen

            if field.trimmed():
                print "No error"
            else:
                self.show_msgbox_error()
                break
So liegt der Break nicht in der For-Schleife, sondern im else-Block. Damit wird nur dann abgebrochen, wenn ein Fehler vorliegt.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

So Leute, ich hole mir mal von euch den Gnadenschuss ab :-)

Hier erst einmal der Code.

Code: Alles auswählen

    def check_inputs(self):
        editFields = [self.ui_pp_feedback.textEditFeedback]

       lineFields = [self.ui_pp_feedback.lineEditSubject]

        print editFields, lineFields # [<PyQt4.QtGui.QTextEdit object at 0x0292D300>] [<PyQt4.QtGui.QLineEdit object at 0x0292D390>]

        for editField in editFields:
            self.var_editfield = editField.toPlainText()
            print self.var_editfield

        for lineField in lineFields:
            self.var_linefield = lineField.text()
            print self.var_linefield

        if not self.var_linefield.trimmed():
            self.show_msgbox_error()
        else:
            if not self.var_editfield.trimmed():
                self.show_msgbox_error()
            else:
                print "Do Something"
Was habe ich getan bzw was hatte ich vor?
Also, in Zeile 2 und 4 habe ich die beiden unterschiedlichen Widgets in unterschiedlichen Listen hinzugefügt. Denn die beiden haben unterschiedliche APIs bzw. unterschiedliche Methoden. Damit ich mir sicher sein kann, dass es sich hierbei tatsächlich um Widgets handelt und nicht etwa um Zeichenketten, die da in den Listen sind. Anhand der Ausgabe sehe ich also, dass es sich hierbei um Widgets handelt. Alles super. Nächster Schritt. Von Zeile 8 bis 14 habe ich zwei For-Schleifen gebaut - einmal für QTextEdit und einmal für QLineEdit. In diesen beiden Schleifen lasse ich einmal in Zeile 9 und 19 die Zeichenketten aus den Widgets geben und speichere sie in den Attributen (self.var_editfield und self.var_linefield). Warum ich hier self() verwende soll in Zeile 16 geklärt sein. Ich will hier auf Attribute zugreifen, die eigentlich in den beiden For-Schleifen sind. In Zeile 16 bis 22 baue ich eine If-Abfrage und benutze hier die trimmed-Methode. Und hier werde ich mir meinen Gnadenschuss holen. Ich weiss, dass in der QT-Dokumenttation folgendes steht:
Returns a string that has whitespace removed from the start and the end.
Jedoch gehe ich erst einmal davon aus, dass es funktioniert :-) Das dies natürlich keine gute, nicht mal annähernd eine zufriedenstellende Lösung ist, kann ich mir fast denken. Daher bin ich gespannt auf eure Reaktion :-)
Antworten