Checkbutton Frage/Problem - Anregung gesucht

Fragen zu Tkinter.
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

@BlackJack: Ok, ich Versuchs mal.

self dient doch dazu um die variable außerhalb einer Funktion aufrufen zu können
checkbox hier is die variable bzw die liste
und mit get wollte ich quasi den Inhalt daraus holen was ja nicht geht da ja man bei listen kein get benutzen kann

Ich hatte ja vorher die StringVar an die Variable gehängt mit append, heißt ich hab jetzt in self.checkbox die StringVar Objekte
In einer anderen Funktion versuchte ich mir das gespeicherte auszugeben mit print(self.checkbox) (self deswegen da ich die Variable aus einer anderen Funktion aufrufen will)
und bekomme dafür die Zeichenkettendarstellung [<tkinter.StringVar object at 0x3140310>, <tkinter.StringVar object at 0x3140510>] aber nicht die Objekte selbst die darin enthalten sind.

Aber laut Internet und in meinen Büchern kann man darauf mit get() zugreifen und hier scheitert es ja an der Umsetzung und am Verständnis wie das ganze funktionieren soll.

Und jetzt zu deinen Operatoren.... das is doch eine Fangfrage oder? Laut meinem Verständnis von Operatoren hab ich keine bzw. benutze keine in diesem Fall hier.
Maximal das "in" was in den "for-Schleifen" aber das wars ja auch schon.
Oder ich versteh dich gerade falsch dann tut´s mir Leid wenn ich dich gerade nicht verstehe was du genau von mir erwartest gerade. :K
BlackJack

`self` ist das Objekt auf dem die Methode aufgerufen wurde. Hat also auch den Typ in dem diese Methode definiert wurde. Das dient wie eigentlich alle Objekte dazu Werte und Funktionen zu einer Einheit zusammen zu fassen. Die Funktionen werden dabei zu Methoden mit dem obligatorischen ersten Argument welches immer das Objekt ist auf dem die Methode aufgerufen wurde.

`checkbox` ist der Name eines Attributs das vom `self`-Objekt abgefragt wird, und da Du an diesen Attributnamen im vorherigen Programmverlauf eine Liste bebunden hast, ist das hier jetzt auch tatsächlich eine Liste.

Und von der Liste versuchst Du dann ein Attribut mit dem Namen `get` zu bekommen. Und das geht halt nicht weil Listen kein solches Attribut haben. Wie man an einzelne Elemente einer Liste heran kommt sollte man eigentlich nach jedem Grundlagentutorial wissen. Dafür gibt es den Indexzugriff.

Bei einem `print()` bekommst Du niemals die Objekte selbst ausgegeben ausser in einem einzigen Fall: Bei Zeichenketten. Alles andere muss ja in eine Zeichenkettenrepräsentation umgewandelt werden weil die Ausgabe am Ende Text sein muss. (Hier habe ich jetzt mal grosszügig das Thema Unicode und Kodierungen ignoriert, das wäre an der Stelle noch mal eine zusätzliche Schicht Komplexität.)

Du musst `get()` halt auf den einzelnen Elementen der Liste aufrufen und *das* dann ausgeben. Um etwas mit jedem Element einer Liste zu machen gibt es ``for``-Schleifen. Hier sind wir jetzt aber wieder bei absolutem Basiswissen.

Das mit den Operatoren war keine Fangfrage. Es werden zwei Stück verwendet, der Punktoperator (``.``) und der Indexoperator (``[…]``). Beides sind binäre Operatoren, das heisst sie erwarten zwei Operanden.

Beim Punktoperator muss links ein beliebiger Ausdruck stehen der zu einem Objekt ausgewertet wird und rechts ein Name der als Attribut auf dem ersten Operanden existiert. Das Ergebnis ist der Wert des Attributs. (Hier habe ich mal die Fälle „Objekt kann auch auf nicht existierende Attribute reagieren”, und Properties weggelassen.)

Beim Indexoperator muss davor ein beliebiger Ausdruck stehen der zu einem Objekt ausgewertet wird das den Indexzugriff erlaubt und zwischen den Klammern ein beliebiger Ausdruck den der andere Operand als Indexwert akzeptiert. Der Ausdruck in den Klammern wird grundsätzlich ausgewertet bevor der Indexzugriff gemacht wird. Das Ergebnis ist was auch immer der erste Operand für den Indexwert liefert.

Punkt- und Indexoperator haben die gleiche Bindungstärke, das heisst der gesamte Ausdruck wird von links nach rechts ausgewertet.

Oder auf ”Buchstaben verteilt” was ich ja gefragt hatte:

Code: Alles auswählen

self.checkboxen.get[1]

# =>

a = self          # Das Objekt auf dem die Methode aufgerufen wurde.
b = a.checkboxen  # Das Attribut `checkboxen`, eine Liste mit `StringVar`-Objekten.
c = b.get         # FEHLER weil Listen kein `get`-Attribut haben.
d = 1
e = c[d]
Zu `d` und `e` kommt es in der Ausführung wegen des `AttributeError` nicht mehr also kann man bei `e` auch nichts über Wert und Typ sagen weil Wert und damit Typ von `c` undefiniert ist.

Ausgerechnet das ``in`` in der ``for … in …:``-Syntax ist übrigens *kein* Operator sondern Teil der Schleifenanweisung. Es gibt aber in der Tat auch den ``in``-Operator. Ebenfalls ein binärer Operator der links einen Ausdruck erwartet der zu einem beliebigen Objekt ausgewertet wird und rechts ein Objekt das den Test implementiert und das Ergebnis ist ein Wahrheitswert.
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

@BlackJack: Puh, viel zu lesen und zu verstehen. Ich werds mir genauer anschauen und probieren aber eine winzige kleine Frage hätte ich noch: Was ist das PY_VAR# (# für eine beliebige Zahl)? Vllt kannst du mir dazu noch eine kleine Erklärung schreiben.

Danke
BlackJack

@Kalli87: Das ist die Zeichenkettendarstellung von `Tkinter.Variable`-Objekten und damit auch von `StringVar`-Objekten. So ziemlich alle Objekte von Datentypen aus dem `Tkinter`-Modul liefern wenn man sie in eine Zeichenkette umwandelt die Zeichenkette unter der der Tk-Interpreter das jeweilige Objekt ansprechen kann. Widgets zum Beispiel den Pfad innerhalb der Widget-Hierarchy im zu dem jeweiligen Widget zu gelangen. Und Tk-Variablen haben entweder einen generierten Namen wie Du ihn beschrieben hast, oder man kann beim erstellen des Objekts einen übergeben. Das kann nötig sein wenn man mehr mit Tk-Arbeitet und auf Tk-Seite Code einen bestimmten Namen erwartet oder wenn es dort bereits eine Variable mit einem bestimmten Namen gibt, für den man auf Python-Seite gerne ein Objekt hätte.

Code: Alles auswählen

In [21]: import Tkinter as tk

In [22]: root = tk.Tk()

In [23]: v = tk.StringVar()

In [24]: print v
PY_VAR0

In [25]: str(v)
Out[25]: 'PY_VAR0'
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

@BlackJack: Das klingt ja voll nach Zeichenkettenformatierung bzw. Verarbeitung von Zeichenketten und wenn ich´s richtig verstanden habe müsste ich so dann auch die PY_VAR zurecht formatieren können bzw. so wäre der Weg um die richtige Ausgabe zu bekommen.
Wenn ich falsch liege bitte berichtige mich.

Danke
BlackJack

@Kalli87: Ja Du liegst falsch. 'PY_VAR0' ist eine Zeichenkette. Mit genau dem Inhalt denn man da sieht. Also ein 'P' gefolgt von einem 'Y' gefolgt von einem '_', und so weiter. Auf dieser Zeichenkette gibt es die Operationen die es auf allen Zeichenketten gibt. Das die Zeichenkette aus einem `StringVar`-Objekt erstellt wurde ”weiss” sie nicht, von einer Checkbox schon gar nichts. Man könnte jetzt natürlich Tk nach einem `StringVar`-Objekt fragen das den Namen hat der dem Wert der Zeichenkette entspricht, aber das wäre Unsinn denn von genau so einem Objekt hat man diese Zeichenkette ja erzeugt. Das sollte man vielleicht nicht machen sondern die Operationen nutzen die `StringVar`-Objekte haben um an die Zeichenkette zu kommen die *darin* gespeichert ist.
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

@BlackJack: Ähm ok, ich werds mir zu hause mal in ruhe anschauen.
Danke
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

Ich meld mich doch eher zurück als gedacht :)
BlackJack hat geschrieben:Du musst `get()` halt auf den einzelnen Elementen der Liste aufrufen und *das* dann ausgeben. Um etwas mit jedem Element einer Liste zu machen gibt es ``for``-Schleifen. Hier sind wir jetzt aber wieder bei absolutem Basiswissen.
Ich versteh worauf du hinaus willst ich hab es auch getestet, nur mit einer einzelnen Ausgabe ohne "for-Schleife", was mir jetzt aber Kopfzerbrechen bereitet ist das ich eine leere Ausgabe bekomme, also man sieht einfach nichts, keine Zahl, kein Buchstabe einfach nichts.
BlackJack

@Kalli87: Für `StringVar`-Objekte die eine leere Zeichenkette beinhalten wäre das das erwartete Ergebnis.
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

Ah ok also werden die Werte nicht richtig an die Checkbox-Variable übergeben.
Also muss ich da nochmal ran
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

Guten Morgen Forum :)
und zwar geht es noch um die checkboxen/checkbuttons, eher um es besser zu verstehen gerade.

Die checkbuttons/boxen sind doch so aufgebaut
text=zeigt die beschriftung an
variable=ist die verbindung zu dieser Checkbox
off/onvalue= den aktiven und deaktivierten wert festlegen
command=um eine Funktion aufzurufen bei Betätigung

Ich bin immer davon ausgegangen das der On-Value mit der variable zusammenhängt sprich sobald aktiv wird die variable mit dem onvalue belegt.
Ich hatte die variable ja immer (self.checkboxen) genannt also "variable=self.checkboxen" und durch testen hatte ich ja immer nur eine leere Ausgabe was laut BlackJack zu erwarten war.
Durch probieren hab ich einfach die "variable" so belegt "variable=self.checkboxen.append(serie_studie)" und schon hatte ich keine leere Ausgabe mehr sondern das gewünschte Ergebnis worauf ich mit eurer Hilfe ja schon ewig dran hänge. (An dieser Stelle fiel mir auch die Sache mit dem StringVar() war weg)
Einziges Problem ist nur noch das jede Checkbox alle Werte bekommt statt nur den einen, eine for-Schleife sollte da ganze dann in den Griff bekommen.

Jetzt hätte ich gern gewusst ob ich hier nun ein Fehler in meinen Gedankengängen hatte was das belegen der checkbox-variable betrifft und was nun mit der StringVar nun is also warum ich diese "eigentlich" weglassen kann.

Danke
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@Kalli87: ich hatte schon gute Hoffnungen, dass das irgendwann was wird. :(
Du weißt welchen Wert variable bei "variable=self.checkboxen.append(serie_studie)" bekommt?!?!?!?!?!?!
variable erwartet einen Wert vom Typ StringVar. Und keine Liste mit StringVars!

Ich habe Dir bereits am 2. April und 10.April empfohlen, diesen ganzen Tk-Kram erst einmal zu vergessen und Dich mit den Grundlagen von Listen und deren Verarbeitung vertraut zu machen. Jetzt haben wir den 20. und es wird mal wieder Zeit zu sagen, ohne Grundlagen kommst Du nicht weiter! Auch wenn Python eine dynamisch typisierte Sprache ist, es gibt trotzdem Typen. Und wenn Du die wild durcheinander wirfst, kann nichts sinnvolles rauskommen, und solange Du das nicht verstanden hast, brauchst Du erst gar nicht weiter zu machen.
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

@Sirius3: Wenn ich dir jetzt sage bzw. schreibe was ich als nächstes machen muss springst du im Dreieck und verlierst den glauben an Menschheit, wenn du diese nicht bereits verloren hast.
Dieser Thread dient ja schon zum Verständnis und mehr als Fragen kann ich nicht.

Einfacher wäre es natürlich wenn man einfach klipp und klar sagt: "Kalli87 pass mal auf dort, dort und dort is der Fehler. Schreib das so hier und dann funktioniert das auch."
Aber das is wahrscheinlich wieder zu einfach um mir mal klipp und klar zu zeigen was richtig wäre und vllt auch zu viel verlangt von euch.

Ich weiß ihr habt eure Prinzipien und wollt das man selbst lernt und nicht nach Lösungen fragt bzw. ihr keine "Hausaufgaben" machen wollt. Aber es sind keine Hausaufgaben es ist ein Projekt was von mir sehr viel abverlangt und das is mir bewusst aber so komm ich auch nicht weiter.

Und ganz ehrlich, ich war froh das durch mein probieren mal keine! leere Ausgabe, PY_VAR# oder <tkinter.StringVar object at 0x3140310> hatte sondern eine vernünftige Ausgabe mit dem was ich die ganze Zeit haben will! Das könnt ihr mir nicht übel nehmen das ich mir Gedanken mache und probiere. Das es nicht der Sinn von programmieren ist auch mir klar.

Das mit den Checkboxen is eher ein Fliegenschiss zu dem was noch alles vor mir liegt......

Vllt sollte man diesen Thread zu "Checkboxen des Grauens" um nennen, so fühlt es sich langsam für mich an.

Danke
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@Kalli87: es ist ja nicht so, dass nicht alle Bausteine zur Lösung hier in diesem Thread schon vorgekommen wären. Du brauchst sie nur zusammenzusetzen. Aber genau da hast Du ja Dein Problem, weil Dir die nötigen Grundlagen fehlen und wenn Du hier alles vorgekaut bekommst, landest Du beim nächsten Problem wieder hier und am Ende ist es wirklich so, dass Leute im Forum Dir das ganze Programm schreiben. Gegen Gedankenmachen und Probieren ist nichts einzuwenden, solange es irgendwo hin führt. Mir scheint es aber so, dass Du im Dunkeln tappst, hin und wieder mal ein Körnchen findest, es aber wieder fallen läßt, weil Du es selbst nicht merkst.
Ich hatte Dir schonmal geschrieben, dass Du Dein Problem in Teile spalten musst. Also wenn ein Checkbutton funktioniert, dieses Prinzip auf viele Checkbuttons übertragen..
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

@Sirius3: Ich bin dabei hab mein Fehler auch gefunden bzw. hab was gefunden was nicht bei mir ganz stimmte.
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

Ihr dürft jetzt feiern!
Habs gelöst :) und ihr seit erlöst von eurer Qual was die Checkboxen betrifft

DANKE
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hast Du es denn jetzt auch verstanden?

(um die "Qual" ggf. weiterzuführen... :mrgreen: )
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

Klaro :D
Oder willst du es jetzt drauf anlegen Hyperion? :twisted:
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Kalli87 hat geschrieben: Oder willst du es jetzt drauf anlegen Hyperion? :twisted:
Irgend wie schon :mrgreen:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

@Hyperion: Dacht ich´s mir doch :D dann leg mal los :mrgreen:
Antworten