Seite 1 von 2
Listboxen
Verfasst: Sonntag 30. Juni 2019, 15:28
von mosimfs
Guten Tag, bin Neueinsteiger hier.
Mein Programm, eine Art Fotobewertung für einen Club. Siehe Anhang.
Mein Problem, ich verwende viele Listboxen mit je einen Eintrag, die ich mit "grid" positioniere.
Nun, auf den letzten Eintrag bzw. die letzte Listbox kann ich zugreifen und auch auswerten, die Anderen kann ich zwar auch auswählen und sie werden auch blau markiert, da müsste ich wahrscheinlich vorher die jeweilige Listbox auswählen können.
Nur wie?
Sorry, Bild einfügen ist nicht so einfach auch das Listing feigelt.
bitte könnt ihr mir helfen!
Re: Listboxen
Verfasst: Sonntag 30. Juni 2019, 17:15
von Sirius3
Eine Listbox mit nur einem Eintrag ist irgendwie unsinnig. Ich verstehe auch Dein Problem nicht. Was willst Du wie auswerten?
Listing kannst Du einfach mit Code-Tag </> hier direkt einfügen.
Re: Listboxen
Verfasst: Sonntag 30. Juni 2019, 20:19
von mosimfs
Danke vorerst für melde.
Abgesehen ob's Sinn macht, die Frage ist:
Kann man per Mausklick eine der Listboxen auswählen und den einen Eintrag auslesen? lg
Re: Listboxen
Verfasst: Sonntag 30. Juni 2019, 21:11
von mosimfs
zum Sinn vom Aufbau:
ich fand vorerst keine bessere Lösung die Einträge so fromatiert darzustellen und durch Auswahl den Eintrag auszulesen.
nochmal, wie wird hier ein Bild eingebunden?
nun der Teil meines Programm:
Code: Alles auswählen
try:
f = open(SO+datei, "r")
x=0
for Text in f:
Text = Text.split(" | ")
Text = str(Text[0])[0:2] + ". " + str(Text[0])[12:17] + " " + \
str(Text[1]) + " "
Text = Text[0:39]
x+=1
if a==0:
Daten(x, Text) # Listbox erzeugen
z = x
if m == 1:
Daten(z, Text)
f.close()
Eingang.config(text= Y+"-Eingänge ", bg="#fff")
Anzeige.bind("<<ListboxSelect>>", Detail) # Eintrag abfragen
except:
Eingang.config(text= " keine Daten vorhanden ", bg="#fff")
z=0
#----------------------------------------------------------------------------
def Daten(x, MEtext):
global Anzeige
Anzeige=Listbox(master=window, height=1, width=35, bd=2, font=("Courier", 13), relief=RAISED)
Anzeige.insert(END, MEtext)
if x <= 26:
Anzeige.grid(column=0, row=x, columnspan=5, pady=3, padx=3, sticky=W)
elif x > 26 and x <= 52:
Anzeige.grid(column=5, row=x-26, columnspan=11, pady=3, padx=3, sticky=W)
elif x > 52 and x <= 78:
Anzeige.grid(column=11, row=x-52, columnspan=16, pady=3, padx=3, sticky=W)
elif x > 78 and x <= 104:
Anzeige.grid(column=17, row=x-78, columnspan=20, pady=3, padx=3, sticky=W)
#----------------------------------------------------------------------------
def Detail(event):
print(Anzeige.get(Anzeige.curselection()))
Button(master=window).grid_forget()
Re: Listboxen
Verfasst: Montag 1. Juli 2019, 05:47
von Sirius3
Was sind denn `a`, `m` oder `Y` und was wird mit `z` gemacht? Einbuchstabige Variablennamen sind nie gut, vor allem, wenn sie noch global sind und aus dem Nichts kommen.
Schreibe Funktionen, benutze kein ›global‹ und benenne Deine Variablen aussagekräftig.
Wenn `a` null ist, dann macht die for-Schleife nichts und `z` wird nicht definiert, was dann zwei Zeilen später zu einem NameError führt, falls `m == 1`, was man aber nicht wissen kann, weil das auch aus dem Nichts kommt.
`Text` ist ein String und wird per `split` zu einer Liste von Strings, dem Du dann wieder den Wert eines Strings zuweist. Variablen sind nicht teuer, man muß sie nicht sofort recyclen.
Ein String per `str` nochmal in einen String umzuwandeln ist sinnlos.
Indexzugriffe vermeiden, und benutze Stringformatierung statt hier mit + zu arbeiten.
Keine nakten `except`, das macht es unmöglich, Programmierfehler zu finden. Wenn Du testen willst, ob die Datei lesbar ist, reicht ein IOError.
`Daten` ist keine Funktion. Funktionen werden nach Tätigkeiten benannt, vergiß dass es `global` gibt, hier willst Du eine Funktion schreiben, die als Rückgabewert die Listbox hat. Was soll `MEtext` bedeuten?
Die vier if-Blöcke unterscheiden sich nur durch column und row. Der Aufruf gehört also hinter die ifs und für column und row kannst Du Variablen benutzen.
Code: Alles auswählen
def create_listbox(window, number, content):
display = tk.Listbox(master=window, height=1, width=35, bd=2, font=("Courier", 13), relief=tk.RAISED)
display.insert(END, content)
if number <= 26:
column = 0
row = number
elif number <= 52:
column = 5
row = number - 26
elif number <= 78:
column = 11
row = number - 52
elif number <= 104:
column = 5
row = number - 78
else:
raise ValueError("number too large")
display.grid(column=column, row=row, columnspan=20, pady=3, padx=3, sticky=tk.W)
return display
Da Du nur EINE globale Variable `Anzeige` hast, kann `Detail` auch nur die letzte Listbox ansprechen. Was ist der Sinn, einen Knopf zu erzeugen, der explizit NICHT angezeigt wird?
Re: Listboxen
Verfasst: Montag 1. Juli 2019, 13:11
von mosimfs
Danke für deine Hilfe, es gibt allerdings auf diese Art keine Anzeige am Display, auch keine Fehlermeldung.
Soweit ich's erkenne, du hast 'grid' halt hinten angestellt.
Sag mir wie kann ich ein Foto das meinen Aufbau zeigt ins Forum stellen.
lg
Re: Listboxen
Verfasst: Montag 1. Juli 2019, 13:23
von __blackjack__
@mosimfs: Du kannst Bilder bei einem Hoster wie imgur.com hochladen und dann hier mit dem img-Tag in den Beitrag einbinden.
Re: Listboxen
Verfasst: Montag 1. Juli 2019, 15:14
von mosimfs
nur kurz: Deine Ausführung funktioniert, weiß nicht warum jetzt. Auch die String's sind für die Katz.
Das Problem mit der Auswahl ist halt das gleiche geblieben. Stimmt, die Listboxen heißen alle Anzeige bzw. jetzt display.
Dennoch jede Listbox hat eine eigene .67967184 .67967744 .67967856 usw. da sollte es doch eine Möglichkeit der Auswahl geben, oder?
lg
Re: Listboxen
Verfasst: Montag 1. Juli 2019, 15:30
von mosimfs
ob's auf diese Art funktioniert

Re: Listboxen
Verfasst: Montag 1. Juli 2019, 15:32
von __blackjack__
@mosimfs: Das geht zwar sicherlich, ist aber der falsche Weg. Statt sich das hinterher irgendwie aus Tk wieder raus zu popeln, sollte man sich die Objekte in Python einfach merken. Zum Beispiel in dem man sie in eine Liste steckt.
Wobei die Listboxen nicht alle `Anzeige` oder `display` heissen, sondern immer nur *eine* davon heisst so. Denn sobald die nächste an den Namen gebunden wird, ist die davor ja eben nicht mehr an diesen Namen gebunden.
Vielleicht suchst Du aber auch `functools.partial()` um die jeweilige Listbox für den Aufruf einer Rückruffunktion beim `bind()` schon mal als Argument zu binden.
Edit: Für das img-Tag musst Du eine URL direkt zur Bilddatei haben, nicht eine URL zu einer Webseite in der das Bild angezeigt wird.
Re: Listboxen
Verfasst: Montag 1. Juli 2019, 17:15
von mosimfs
auch vielen Dank für die Hilfe.
Die Einträge lese ich im Vorfeld aus den eingehenden Mail's der Mitglieder aus. Zum einen die Fotos die zur Bewertung gehen, zum anderen die Bewertungen und alles ladet in Dateien. Im nächsten Schritt geht's zur Auswertung. Den Listenaufbau verwende ich zum auswählen der Teilnehmer und Anzeigen der Bewertung. Das ganze läuft am Raspi rund um die Uhr, voll automatisch. Wenn's wahr ist?
PS. functools.partial() ?? des mit dem Bild einfügen is a nu spanisch.
Re: Listboxen
Verfasst: Dienstag 2. Juli 2019, 08:52
von mosimfs
nur so eine Überlegung,
ich könnte ja die Listboxen über einen Namen mit Index bezeichnen, aber was bringt's?
beim anklicken und auslesen (????.bind("<<ListboxSelect>>", Detail) bzw.(????.get(Anzeige.curselection()))
Wo und wie wird der Name (????) ausgelesen.
eine andere Frage: kann man so einen Beitrag im Forum verschieben oder umbenennen, vielleicht kennen eure Kollegen eine Lösung.
lg aus Scharnstein
Re: Listboxen
Verfasst: Dienstag 2. Juli 2019, 09:08
von mosimfs
und gleich noch ein mal,
im Detail(event), im (event) steht <tkinter.Event object at 0x0000000003CE30F0>
kann ich da was extrahieren?
Re: Listboxen
Verfasst: Dienstag 2. Juli 2019, 09:27
von Sirius3
Du sollst Detail mit Hilfe von functools.partial (wenn Du nicht weißt, was das ist, kannst Du in der Hilfe nachlesen, oder in der Python-Dokumentation) die aktuelle Listbox übergeben. Ich denke, es wäre auch nicht schlecht, alle Listboxen in einer Liste zu sammeln, um später vielleicht alles Selections abzufragen.
Das ist die Lösung. Irgendwo in den Eingeweiden von Tkinter rumzuwühlen ist keine Lösung.
Re: Listboxen
Verfasst: Dienstag 2. Juli 2019, 10:25
von __blackjack__
Wobei im `Event`-Objekt tatsächlich auch das `Widget` steckt das dieses Ereignis ausgelöst hat — als Attribut auf dem Python-Objekt.
Re: Listboxen
Verfasst: Dienstag 2. Juli 2019, 11:44
von mosimfs
Wenn ich lästig sein darf, dieses functools.partial , wie kann ich's anwenden?
Und, dass müsste ja vor dem bind geschehen.
Die Tatsache das sich die Einträge anklicken lassen und sich auf Blau ändern, da muss doch eine Aktion laufen.
Re: Listboxen
Verfasst: Dienstag 2. Juli 2019, 11:56
von __deets__
Hast du dir die Dokumentation mal angeschaut?
https://docs.python.org/2/library/funct ... ls.partial
Da wird das erklaert. Und du kannst damit eben Zusaetzliche Argumente an den callback binden.
Re: Listboxen
Verfasst: Dienstag 2. Juli 2019, 12:42
von mosimfs
Danke, schaut vielversprechend aus!
Ob ich's umsetzen kann? Hmm
Re: Listboxen
Verfasst: Mittwoch 3. Juli 2019, 16:27
von mosimfs
Hallo, ich komme nicht recht weiter.
`functools.partial()`, das verstehe ich nicht, kann's nicht einsetzen.
Ok, def Detail(event) lässt sich auslesen: event.widget.get (int(event.widget.curselection()[0])) und erspart mir den Listboxname Global zu setzen.
Daß, wiederum müsste noch auch mit "<<ListboxSelect>>",l funktionieren. zB. print("<<ListboxSelect>>", Detail)
gibt "<<ListboxSelect>> <function Detail at 0x0000000003D7EE18>" aus. Jetzt richtig extrahieren und einsetzen statt
Listboxname .bind("<<ListboxSelect>>", Detail). Wer kann es?
Nochmal zum Sinn der Ausführung: Am Raspi eine Benutzerfreundliche grafische Oberfläche gestallten, da geht kein Weg um Tkinter vorbei oder.
Eine Listbox und die Clubmitglieder per Scrollbar auswählen gefällt mir nicht.
Wäre schön wenn's brauchbare Ideen gib.

lg
Re: Listboxen
Verfasst: Mittwoch 3. Juli 2019, 16:39
von __deets__
Was an functools.partial verstehst du nicht? Was hast du versucht? Es nunmal die Loesung fuer dein Problem.
Und natuerilch kannst du auch andere Toolkits wie Qt oder Kivy nutzen. Nur sind solche Probleme auch dort zu loesen, und die Mittel der Wahl sind die gleichen.