Checkbutton Frage/Problem - Anregung gesucht

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

@Sirius3: :D ok ok bevor wir wirklich noch bis Weihnachten hier sitzen ;)
Ich hab jetzt bei "datum_ausgabe" und bei "serie_studie" das self entfernt ^^

Ich denke mal dass das Objekt vom Typ "liste" sein müsste.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Kalli87 hat geschrieben:Ich denke mal dass das Objekt vom Typ "liste" sein müsste.
Schade, zweiter Versuch ;-) Kleiner Hinweis: Du hattest es schon richtig.
Das Leben ist wie ein Tennisball.
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

@EyDu: Etwa wieder das mit dem StringVar? Hatte ehrlich gesagt gehofft das ich das so lösen konnte ^^ da hab ich mich wohl getäuscht
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@Kalli87: im Moment gerade ein IntVar, weil Du on- und off-Value wieder entfernt hast. "datum_ausgabe" hatte ich jetzt gar nicht auf dem Schirm, weil das von irgendwo außerhalb Deines Code-Schnipsles kam. Also bleibt noch mindestens ein Attribut das nicht sein sollte.
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

@Siruis3: Bist du dir da ganz sicher? Ich würde dir da jetzt voll widersprechen, aus dem Grund weil:
cursor liegt außerhalbe
ueberframe liegt ebenso außerhalb
list_checkbox liegt genauso außerhalb

Code: Alles auswählen

            
            self.cursor.execute("select bilder.studie_nr, bilder.serie_nr, bilder.image_nr from bilder, patient where patient.patnu=bilder.patnu and patient.patnu=%s", [self.eingabe.get()])
            self.checkbox=StringVar()
            for row,(studie, serie, image) in enumerate(self.cursor, 1):                
                checkboxen=[]
                label_data = \
                [
                    (row, 'lightblue'),
                    (datum_ausgabe, ''),
                    (image, ''),
                    (serie, ''),
                    (studie, ''),
                ]
                serie_studie=('Serie: {} Studie: {}'.format(serie,studie))
                checkboxen.append(self.checkbox)

                for column, (text, background) in enumerate(label_data):
                    Label(self.ueberframe, text=text, relief='sunken', anchor=CENTER, background=background).grid(row=row, column=column, sticky=NSEW)
                Checkbutton(self.ueberframe,text=serie_studie,variable=self.checkbox, onvalue=serie_studie, offvalue="",command=self.list_checkbox).grid(row=row, column=5)
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

Problem besteht jetzt aber das immer nur ein Checkbutton aktiv bleibt, klick ich einen zweiten an is der erste deaktiviert
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Und das sind wir wieder am Anfang des Kreises angekommen... Lies dir doch bitte den gesamten Thread noch einmal in Ruhe durch und versuche die Ratschläge zu verstehen. Du korrigierst hier ständig einen Fehler und baust dafür einen alten wieder ein. Das ist Raten, nicht Programmieren.
Das Leben ist wie ein Tennisball.
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

@EyDu: Und das is das was ich nicht verstehe. Ich weiß das ich die StringVar an eine liste hängen muss, was ich ja auch mache. Aber trotzdem es nicht geht und da kann ich die ganzen Thread 5 mal lesen und ich seh es trotzdem nicht.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@Kalli87: Und wieviele StringVars hast Du in Deine Liste gehängt? Und achte darauf, was an self gebunden wird und was nicht :wink:.
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

@Siruis3: Danke weiß ich nicht mehr wo vorne oder hinten is :?
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

ok bitte mal Schritt für Schritt damit ich den Fehler mal sehe.
@Siruis3: Du fragst ja wie viele StringVar ich an meine Liste hänge.
Mit "self.checkbox=StringVar()" setze ich doch die Variable "self.checkbox" mit "StringVar()" fest.
Danach hänge ich das ganze mit "self.checkboxen.append(self.checkbox)" an meine Liste die ich vor der "for-Schleife" definiert hatte, das mit "self.checkboxen=[]".

Für mich heißt doch das im Klartext, da es durch die Schleife läuft, das immer was meine Liste gehangen wird.

Code: Alles auswählen

            
            self.cursor.execute("select bilder.studie_nr, bilder.serie_nr, bilder.image_nr from bilder, patient where patient.patnu=bilder.patnu and patient.patnu=%s", [self.eingabe.get()])
            checkboxen=[]
            for row,(studie, serie, image) in enumerate(self.cursor, 1):
                self.checkbox=StringVar()
                checkboxen.append(self.checkbox)
                label_data = \
                [
                    (row, 'lightblue'),
                    (datum_ausgabe, ''),
                    (image, ''),
                    (serie, ''),
                    (studie, ''),
                ]
                serie_studie=('Serie: {} Studie: {}'.format(serie,studie))
                for column, (text, background) in enumerate(label_data):
                    Label(self.ueberframe, text=text, relief='sunken', anchor=CENTER, background=background).grid(row=row, column=column, sticky=NSEW)
                Checkbutton(self.ueberframe,text=serie_studie,variable=self.checkbox, onvalue=serie_studie, offvalue="",command=self.list_checkbox).grid(row=row, column=5)
Und der zweiten Hinweis von dir darüber Grüble ich immer noch was du genau meinst.
Ich glaub langsam für eure Hinweise sollte man studiert haben ;)

ps.: Um am ende auf den Inhalt zu zugreifen muss ich doch mit get() arbeiten und das doch bei "self.checkbox.get()" da bekomm ich doch den genauen Inhalt raus. (sieht man hier jetzt natürlich nicht aber das stimmt soweit ich es erlesen habe)

pps.: Wo sitzt der Fehlerteufel? :evil:
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@Kalli87: na jetzt hast Du doch den wesentlichen Punkt schon wieder geändert. Also hätte ich ein "ah, jetzt hab ich's endlich kapiert und alles richtig gemacht" erwartet. Da zum Schluß aber eine Frage steht, schau doch nochmal an, was der Unterschied zwischen jetzt und vorher ist.

Zum hundertsten Mal "self": Variablen, die in einer Schleife geschrieben werden, sind höchst selten sinnvollerweise Attribute. Und "self.cursor" sollte kein "self" haben, weil cursor etwas kurzlebiges sind, die man sich nicht über einen Methodenaufruf merken muß.
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

@Siruis3: Ich weiß das du genauso langsam kochst wie ich :D aber das mit dem cursor is sicher jetzt nicht das Problem was ich hier habe.

War meine Schritt für Schritt Erklärung falsch oder richtig?? Und nein ich habs immer noch nicht kapiert warum das mal so und dann mal so is.
Ich hab mir mehr als 4 verschiedene Varianten angeschaut es versucht nachzuvollziehen und auch für meine Sache umzusetzen aber *piep* Axt im Wald es funktioniert immer nur ein Checkbutton richtig.

p.: Langsam könnte ich :cry:

Eine vernünftige Erklärung wäre echt toll.....
Und bitte, und ich bitte euch wirklich, lasst jetzt bitte diese komischen Hinweise, mir brumt der Schädel......
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

Sorry für meinen kleinen Nervenzusammenbruch gestern aber sich immer wieder im Kreis zu drehen kann einen schon echt an den Rand der Verzweiflung bringen. Also sorry nochmal :oops:
Kalli87
User
Beiträge: 281
Registriert: Montag 10. November 2014, 11:27

Ich versuch mein Glück nochmal obwohl das vllt schon arg ausgereitzt wurde.

Code: Alles auswählen

            checkboxen=[]
            self.checkbox=[]
            for row,(studie, serie, image) in enumerate(cursor, 1):
                self.checkbox=(StringVar())
                checkboxen.append(self.checkbox)
                label_data = \
                [
                    (row, 'lightblue'),
                    (datum_ausgabe, ''),
                    (image, ''),
                    (serie, ''),
                    (studie, ''),
                ]
                serie_studie=('Serie: {} Studie: {}'.format(serie,studie))

                for column, (text, background) in enumerate(label_data):
                    Label(self.ueberframe, text=text, relief='sunken', anchor=CENTER, background=background).grid(row=row, column=column, sticky=NSEW)
                Checkbutton(self.ueberframe,text=serie_studie,variable=self.checkbox, onvalue=serie_studie, offvalue="",command=self.list_checkbox).grid(row=row, column=5,sticky=E)
Ich hab mir jetzt die Seiten hier im Thread mehrmals gelesen und bin auf gewisse Dinge gestoßen.
Der Code hier funktioniert ja soweit bis auf das Problem was schon ganz am Anfang beschrieben wurde und was jetzt wieder aufgetreten ist, sprich nur ein Checkbutton funktiniert richtig.

Jetzt zu dem was ich erlesen haben. Ihr schreibt das die StringVar in eine Liste übertragen/gespeichert werden müssen damit das Checkbuttons richtig funktionieren, wenn ich das richtig verstanden habe.
Meine Vermutung war ja das ich so:
checkboxen=[]
self.checkbox=StringVar()
checkboxen.append(self.checkbox)
das ganze in eine liste speichere. (Jetzt nur mal grob dargestellt der eigentliche code steht ja darüber)
Kommt das so ungefähr hin?

Meine frage dazu wäre aber wenn ich die StringVar in eine liste packe wie hier in diesem Fall funktioniert ja trotzdem nur der eine Checkbutton richtig. Daher denk ich dass das so nicht richtig funktioniert.

Der nächste Versuch den ich unternommen hatte war:
checkboxen.append(StringVar())
so würde ich die StringVar direkt in die Liste speichern statt wie oben beschrieben.
Das Problem was dabei aber aufkommt ist, das ich dann nicht mehr mit get() arbeiten kann da eine Listen-Objekt nie das Attribut "get" hat.
Da kommt mir natürlich in den Sinn wie ich dann auf die gespeicherten Dinge in der Liste zu greifen kann wenn das nicht mit "get" geht?
Ohne "get" sieht ja die ausgabe so aus: <tkinter.StringVar object at 0x2809310>

Ein anderer Hinweis von euch war "vergleiche den "on"-Wert der Checkbutton.
Meine Frage dazu wäre: Wie denn? In keinem Beispiel was ich gesucht und gefunden habe wurde der "on"-Wert verglichen.

Ein anderer Hinweis war das die "self.checkbox=StringVar()" überschrieben wird, da diese ja in der Schleife steht, spaßeshalber hatte ich Sie vor die Schleife gesetzt und schon ging ja das ganze mit der Wertübergabe aber dafür gingen die Checkbuttons nicht mehr richtig. Da immer nur einer Aktiv bleiben konnte. Bzw. deswegen sollte ich diese in eine Liste speichern aber da gabs ja wieder ein anderes Problem was ich schon beschrieben habe.

Im großen und ganzen kann ich jetzt sagen das alles mit der StringVar zusammenhängt, wo Sie steht und wie diese verwendet werden soll.


Zum Abschluss jetzt meine genaue Frage/Fragen:
Wie soll ich nun weiter verfahren?
Welcher Hinweis ist nun der für mich am geeignetsten oder sind alle Hinweise für mich relevant?


Danke

Edit: Was unterstrichen ist wurde hinzugefügt
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Worin besteht denn der Unterschied zwischen Zeile 1 und 2? Bzw. wieso heißt eine Exemplarvariable ``checkbox`` (also *Singular*), obwohl sie doch eine Liste ist und *beliebig* viele Objekte aufnehmen kann? Und wieso ist ``checkboxen`` nur lokal? Brauchst Du die Daten darin nach verlassen der Methode nicht mehr?

Dir ist schon klar, dass in Zeile 4 der Name ``self.checkbox`` an ein vollkommen anderes Objekt gebunden wird als in Zeile 2? Und das in *jedem* Schleifendurchgang? Und um welchen Typen es sich dabei handelt? Und dass es da sinnlose Klammern gibt? Also dass wirklich bei jedem Durchgang ein *neues* Objekt an diesen Namen gebunden wird? Und dass *nach* dem letzten Durchgang damit darin auch stest der *letzte* erzeugte Wert stehen bleibt?

Auch wenn ich ehrlich gesagt den Thread nicht wirklich verfolgt habe, wundert es mich, dass Du an diesen Punkten offenbar immer noch keine Klarheit hast :!:

Wenn Du *viele* Objekte irgend wie verwalten willst, dann brauchst Du einen Container, wie z.B. eine Liste. Das ist an sich schon ok und vernünftig. Aber wozu verwaltest Du dann noch ein *einzelnes* Objekt (s. erste Frage)? Was willst Du mit dem Namen ``self.checkbox`` erreichen? Wozu willst Du den später nutzen?
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: Danke für die schnelle Antwort, du hast schon recht das in dem von mir gepostetem Code offensichtliche fehler sind. Ich bin Schritt für Schritt alles durchgegangen und hab dementsprechend alles abgeändert.
Sobald ich jetzt aber ein Checkbutton anklicke bekomm ich diese Ausgabe.

[<tkinter.StringVar object at 0x3011310>, <tkinter.StringVar object at 0x3011510>]

Und das bereitet mir Kopfzerbrechen. Was ich daraus erkennen kann ist das es sich um 2 Objekte handelt. Nur wie wandele ich das ganze jetzt so um das die Ausgabe wieder stimmt? "get" funktioniert ja nun nicht mehr.

Google hilft mir da leider auch nicht weiter oder hab ich wieder was falsch gemacht?

Code: Alles auswählen

            self.checkboxen=[]
            for row,(studie, serie, image) in enumerate(cursor, 1):
                self.checkboxen.append(StringVar())

                label_data = \
                [
                    (row, 'lightblue'),
                    (datum_ausgabe, ''),
                    (image, ''),
                    (serie, ''),
                    (studie, ''),
                ]
                serie_studie=('Serie: {} Studie: {}'.format(serie,studie))

                for column, (text, background) in enumerate(label_data):
                    Label(self.ueberframe, text=text, relief='sunken', anchor=CENTER, background=background).grid(row=row, column=column, sticky=NSEW)
                Checkbutton(self.ueberframe,variable=self.checkboxen,text=serie_studie,onvalue=serie_studie, offvalue="",command=self.list_checkbox).grid(row=row, column=5,sticky=E)
Zu deiner frage was ich damit anstellen will: Die Checkbutton bekommen die Studie- und Seriennummer zugewiesen wenn der jeweilige Checkbutton angeklickt wurde soll dessen Daten anhand der Nummern (Studie und Serie) verschickt werden, soweit der Plan aber das steht noch nicht zur Debatte. Bis jetzt versuch ich nur die Nummern richtig abzufangen was bis jetzt nicht funzt.
BlackJack

@Kalli87: Wieso funktioniert `get()` nicht mehr? Auch bei Objekten die man in eine Liste steckt funktionieren *auf diesen Objekten* natürlich die Methoden. Und natürlich *nicht* auf der *Liste* — falls das Dein Verständnis von Listen gewesen sein sollte.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Schau Dir mal diesen Code an und überlege, *was* ausgegeben wird:

Code: Alles auswählen

class Button:

    def __init__(self, command):
        self.command = command
        
    def get(self):
        return self.command
        
buttons = [Button("mache dies!"), Button("Mache was anderes!")]

print(buttons[1].get())

for button in buttons:
    print(button.get())
(Die Methode ``get`` ist natürlich unpythonisch - ich habe das nur als Namen gewählt, weil es da bei Tk offenbar etwas gibt, was so heißt)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Hyperion: Die `Variable`-Objekte von `Tk` sind ”Observables” die genau einen Wert kapseln und bei denen man sich registrieren kann wenn man informiert werden möchte wenn dieser eine Wert gesetzt (oder abgefragt oder ”undefiniert”) wird. Die Objekte haben `get()`, `set()`, und `trace()` — letzteres ist die Methode mit der man Rückruffunktionen registriert. Man könnte sich jetzt einen Namen für den gekapselten Wert ausdenken und ein Property statt `get()` und `set()` verwenden, aber da kommt dann die Frage wo man Properties und wo man Methoden verwenden sollte wenn mehr passiert als eine ”leichtgewichtige” Berechnung die kaum mehr als ein setzen/abfragen eines Wertes ist und wo die Grenze ist. Bei `Variable`-Objekten können beliebig viele Rückruffunktionen aufgerufen werden, die beliebig komplexe Aktionen durchführen können. Ob nun ``answer = variable.get()``/``variable.set(42)`` oder ``answer = variable.value``/``variable.value = 42`` halte ich für Geschmackssache.
Antworten