Hidden Value Übergabe in Listbox

Fragen zu Tkinter.
Antworten
sommerschnee
User
Beiträge: 7
Registriert: Dienstag 19. August 2014, 20:02

Moin Forum,

Die Theorie:
Ich lasse mir die Inhalte einer Spalte der DB Tabelle in einer Listbox ausgeben. Sobald eine
Zeile selektiert wurde übergebe ich deren Inhalt per bind() Methode irgendwo anders hin und
mache damit weis Gott was...
Soweit kein Problem!
Aus der Auswahl heraus sollen nun aber neue Auswahlmöglichkeiten resultieren, welche in Abhänigkeit
zueinander stehen. Ist ja gängige Praxis...
Selbstverständlich sollen die Ergebnisse anhand des Primary Keys aus der DB ausgelesen werden und nicht anhand des Wertes!
Dieser ist zwar auch eindeutig, muss es aber nicht zwingend bleiben. Da ich aus dem PHP Bereich komme, wäre meine erste Idee
ein "hidden value" zu übergeben welche den Wert des Primary Keys enthält... (Ich bin mir nicht sicher ob der Terminus im Python
Kontext richtig ist, also verzeit mir wenn nicht :wink: )
Genau das ist wohl der 'tricky' Teil an dem ganzem! Ich möchte NICHT den Listbox eigenen Index auslesen, was ja mit curselection()
Problemlos möglich ist.
Im Prinzip muss ich also entweder einen versteckten Wert übergeben oder den Listbox Index durch den Wert der ID des ausgewählten Elements
aus der DB ersetzen...
Also das was der Kollege hier http://stackoverflow.com/questions/1075 ... er-listbox schon versucht hat. Der dort
vorgeschlagene Lösungsweg scheint mir jedoch wenig praktikabel da sich die Indexe ja verändern können, zum Beispiel durch Löschen oder
hinzufügen eines Eintrags.

Der Ansatz:

Code: Alles auswählen

from tkinter import *
  

window = Tk()
  
class ListboxSelect:
      
    def __init__(self):
        self.list = Listbox(window)
        
        # das ist nur eine beispiel Liste, normal wäre das das Resultat einer
        # DB Abfrage
        ls = [[1, "foo"], [2, "bar"], [3, "lala"], [4, "dubi"]]
        
        for item in ls:
            self.list.insert(END, item[1])
            # Wenn ich das richtig sehe wäre ja hier der punkt um die ID dem Index zu zuweisen....
        
        self.list.bind("<Double-Button-1>", self.onselect)
        
        self.list.pack()

    def onselect(self, event):
        #irgendwo hier muss ich die ID des gewählten Eintrags
        #zur weiteren Verarbeitung einer Variable zuordnen...
        widget = event.widget
        selection = widget.curselection()
        value = widget.get(selection)
        print("Ausgewählt: " + str(value))

ListboxSelect()

window.mainloop()
Möglich das ich den Wald vor lauter Bäumen nicht sehe oder einfach einen Denkfehler habe, auch nach intensiver Suche
bin ich der Lösung noch nicht wirklich näher gekommen... Vielleicht suche ich aber auch nur nach den falschen Dingen! :K
Also wenn jemand einen hilfreichen Tip oder sogar eine Lösung am Start hat wäre ich unendlich dankbar...

Gruß Markus
Gelber Schnee ist kein Zitroneneis!
BlackJack

@sommerschnee: Ich würde über den `Listbox`-Index gehen. Und dann halt keine Einträge einfügen oder löschen die man nicht auch in der Liste wo die tatsächlichen Daten vorgehalten werden einfügt oder löscht. Beziehungsweise würde ich diese Änderung nur an der Liste vornehmen und den `Listbox`-Inhalt einfach komplett löschen und neu befüllen.

Ist nicht schön, aber ist halt Tk. Und Listbox. :-)
sommerschnee
User
Beiträge: 7
Registriert: Dienstag 19. August 2014, 20:02

Hmmm... danke mal dafür aber das stellt für mich keine Lösung da!
Ich kann mir einfach nicht vorstellen das es da keine Lösung zu gibt, ich bin doch sicher nicht der einzige der das versucht hat!
Wie gesagt das ist ja eigentlich gängige Praxis... :?
Gelber Schnee ist kein Zitroneneis!
BlackJack

@sommerschnee: Warum stellt das keine Lösung dar? Und nein, Du bist sicher nicht der einzige der so etwas gesucht und nicht gefunden hat. Nur weil mehrere Leute etwas suchen, heisst das ja nicht, dass es da auch etwas zu finden geben muss. ;-)

Edit: Wenn es keine `Listbox` sein muss könnte man eventuell ein `ttk.Treeview` verwenden.
sommerschnee
User
Beiträge: 7
Registriert: Dienstag 19. August 2014, 20:02

@BlackJack: Korrigiere mich bitte falls ich das falsch verstehe aber es kann ja sein das der erste eintrag die id 1, der nachste die id 5 un der übernächste die id 27 trägt...
Wenn Einträge in der Datenbank oft geändert werden in Form von Löschen und hinzufügen ist das ja nicht wirklich unüblich.

Das bedeutet ich müsste das mapping ja jedes mal im Quelltext korrigieren wenn sich in der DB was ändert, oder nicht?!

Gruß Markus

edit: Das mit Treeview könnte eine Möglichkeit sein, werde mal prüfen ob das eine Sinnvolle Alternative darstellt.... Danke
Gelber Schnee ist kein Zitroneneis!
BlackJack

@sommerschnee: Ich verstehe das Problem(?) nicht? Welche IDs die Datensätze in der DB haben und ob die sich ändern, hat doch mit der vorliegenden Aufgabenstellung nichts zu tun. Im Quelltext muss da überhaupt nichts geändert werden.
sommerschnee
User
Beiträge: 7
Registriert: Dienstag 19. August 2014, 20:02

Möglich das ich es etwas unverständlich formuliert habe,

Wenn ein Element aus der Liste ausgwählt wurde soll eine weitere Liste befüllt werden mit Elementen die dazu passen,
dass heist das die nächste Liste über eine Abfrage befüllt wird für die ich ja die ID des ausgewählten Elements benötige:

Code: Alles auswählen

SELECT eintrag FROM tabelle WHERE id = <id des ausgewählten elements>
Verstehst du jetzt was ich meine?
Oder verstehe ich nicht was du meinst?
:?:
Gelber Schnee ist kein Zitroneneis!
BlackJack

@sommerschnee: Ich sehe da immer noch nicht das Problem‽ Den Index des `Listbox`-Eintrags benutzt man als Index in die Liste mit den Datensätzen und in dem Datensatz steht dann ja die Datenbank-ID für diesen Datensatz. Du darfst das `ls` aus dem Ausgangsbeitrag halt nicht ”wegwerfen” sondern musst Dir das merken.
sommerschnee
User
Beiträge: 7
Registriert: Dienstag 19. August 2014, 20:02

@BlackJack: Also irgndwie stehe ich auf dem Schlauch!
Kannst du mir villeicht anhand eines kleinen Beispiels zeigen wie du das meinst?
Gelber Schnee ist kein Zitroneneis!
BlackJack

@sommerschnee: Na Du hast doch die Liste mit den Datensätzen, also im Beispiel in Deinem ersten Beitrag `ls` wo DB-ID und Text als Elemente drin stecken. Ein Index in diese Liste entspricht einem Index in der Listbox. Wenn Du also über `curselection()` den/die ausgewählten Indizes ermittelst hast Du die Indizes in die `ls`-Liste und kommst darüber doch auch wieder an die Datenbank-ID der ausgewählten Einträge. Ist halt eine zusätzliche Indirektion. Man müsste halt das Datenbankergebnis an das Objekt binden und dann in der `onselect()` darauf zugreifen (ungetestet):

Code: Alles auswählen

        database_ids = [self.ls[i][0] for i in widget.curselection()]
Und bitte einen besseren Namen als `ls` wählen. :-)
sommerschnee
User
Beiträge: 7
Registriert: Dienstag 19. August 2014, 20:02

@BlackJack: Vielen vielen Dank!!!

Manchmal kann es ja so einfach sein :-)
...jetzt wo ich die Lösung sehe, schäme ich mich ja schon fast gefragt zu haben!

Vielen Dank nochmal

Gruß Markus
Gelber Schnee ist kein Zitroneneis!
Antworten