Hallo Leute, ich such schon seit einiger Zeit die Möglichkeit mit Tkinter eine Dropdownbox zu erstellen, in etwa so:
bin aber immer noch auf der suche
zur not steig ich auf wxPython um wenn:
1. sowas dort möglich ist (?)
2. ich die GUI hauptsächlich in Tkinter aufbaue und die Dropdownbox mit wxPython einfach "zwischenquetsche" kann (?)
Dropdown Box mit Tkinter // Listbox Problem
-
- User
- Beiträge: 419
- Registriert: Sonntag 3. September 2006, 15:11
- Wohnort: in den weiten von NRW
- Kontaktdaten:
Tix hat sowas. Ansonsten gibts die Tkinter.Listbox, allerdings müsstes du dir da selbst etwas basteln. Nr. 2 wird nicht möglichsein. Wobei, wenn man in 2 threads ein Tkinter und eine andere GUI laufen lässt, die übernanderlegt, die Fensterränder entfernt, könnte es klappen.
okay das mit der Listbox scheint mir zu passen
aber wie definier ich die position der Listbox in der gui?
http://effbot.org/tkinterbook/listbox.htm hilft mir auch nicht mehr weiter leider :/
edit: ich habs hinbekommen
aber wie definier ich die position der Listbox in der gui?
http://effbot.org/tkinterbook/listbox.htm hilft mir auch nicht mehr weiter leider :/
edit: ich habs hinbekommen
Code: Alles auswählen
listbox.place(x=30, y=600, width=80, height=50)
Was versteht man unter Layout-Manager?
So ich hab nun ein paar Listboxes erstellt und rumexperimentiert,
aber ich bekomm es nicht hin das wenn ich 2 oder mehr Listboxen habe,
dass dann bei Auswahl in der 2. die Auswahl in der 1. Listbox bleibt,
sie verschwindet immer.
Ich hab auch schon mit selectmodes rumgespielt,
aber das scheint nichts zu nützen da diese nur innerhalb einer Listbox funktionieren.
Wie kann ich diese Problem denn lösen,
das tkinterbook gibt auch keine weiteren Informationen.
So ich hab nun ein paar Listboxes erstellt und rumexperimentiert,
aber ich bekomm es nicht hin das wenn ich 2 oder mehr Listboxen habe,
dass dann bei Auswahl in der 2. die Auswahl in der 1. Listbox bleibt,
sie verschwindet immer.
Ich hab auch schon mit selectmodes rumgespielt,
aber das scheint nichts zu nützen da diese nur innerhalb einer Listbox funktionieren.
Wie kann ich diese Problem denn lösen,
das tkinterbook gibt auch keine weiteren Informationen.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Guck mal hier.sorgenlos hat geschrieben:Was versteht man unter Layout-Manager?
Kurz zusammengefasst sind das Helfer die sich darum kümmern, dass die Widgets optimal auf dem Programmfenster plaziert sind, d.h. wenn das Fenster vergrößert wird, dass die Widgets dann immer noch an den richtigen Stellen sind.
Das ist quasi das Gegenteil von dem was Visual Basic immer geboten hat und wenn man mal darüber nachdenkt ist das auch viel angenehmer zu nutzen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Das Programm an dem ich grad schreibe hat an die
40 Entry-Felder
50 Labels
und eine Hand voll Buttons
und dazu werden noch knapp 10 Listboxen hinzukommen wenn ich das
Problem mit dem Fokus nicht hätte
Der Quelltext sieht dementsprechend aus
ich habe alle Widgets mit dem place-Manager verwaltet,
würde es mir "Quellcodezeilen" ersparen wenn ich mit "Packer" oder "Gridder" arbeite?
40 Entry-Felder
50 Labels
und eine Hand voll Buttons
und dazu werden noch knapp 10 Listboxen hinzukommen wenn ich das
Problem mit dem Fokus nicht hätte
Der Quelltext sieht dementsprechend aus
ich habe alle Widgets mit dem place-Manager verwaltet,
würde es mir "Quellcodezeilen" ersparen wenn ich mit "Packer" oder "Gridder" arbeite?
Eigentlich ist das erstmal egal weil der Place-Layoutmanager dafür einfach das falsche Werkzeug ist.
Quelltextzeilen sparst Du wenn Du sich wiederholende Code-Abschitte, die nur in "Daten" variieren, in Schleifen steckst.
Und falls das bis jetzt alles direkt in einem Widget steckte, solltest Du Dir überlegen es auf mehrere Container auf zu teilen, um mehr Übersicht im Quelltext und vielleicht sogar in der Anzeige zu schaffen.
Quelltextzeilen sparst Du wenn Du sich wiederholende Code-Abschitte, die nur in "Daten" variieren, in Schleifen steckst.
Und falls das bis jetzt alles direkt in einem Widget steckte, solltest Du Dir überlegen es auf mehrere Container auf zu teilen, um mehr Übersicht im Quelltext und vielleicht sogar in der Anzeige zu schaffen.
Indem nicht alle Widgets auf dem Fenster platziert werden, sondern Sachen die zusammengehören in Frames gruppiert werden, und diese dann auf dem Fenster platziert werden.
Zum Beispiel kann man je ein Label plus dazugehöriges Entry in einen Frame stecken. Oder eine Gruppe von Labels und Entries in einen Frame mit Grid-Layout, usw.
Zum Beispiel kann man je ein Label plus dazugehöriges Entry in einen Frame stecken. Oder eine Gruppe von Labels und Entries in einen Frame mit Grid-Layout, usw.
An Introduction to Tkinter und Thinking in Tkinter sind zwei nützliche Texte zum Thema Tkinter-Programmierung.
edit: Danke BlackJack, dass sieht sehr gut aus, da werde ich mich mal durchlesen-arbeiten!
Ich will nich für jedes meiner Probleme ein neues Thema eröffnen deswegen kommts hier rein,
hat ja auch was mit Listboxen zu tun, und zwar hab ich eine Listbox mit 2 Einträgen.
Ich kann meine Selection mit einem Button auslesen lassen und den die Selection in der Shell printen lassen.
Vom Prinzip her ziemlich simpel bis auf den Fehler:
ich versteh nicht wieso lb nicht "defined" sein soll, dass ist doch in Zeile 8 passiert...
Vielleicht ist der Fehler zu einfach zu beheben, dass ich nicht drauf komme
Ich will nich für jedes meiner Probleme ein neues Thema eröffnen deswegen kommts hier rein,
hat ja auch was mit Listboxen zu tun, und zwar hab ich eine Listbox mit 2 Einträgen.
Ich kann meine Selection mit einem Button auslesen lassen und den die Selection in der Shell printen lassen.
Code: Alles auswählen
from Tkinter import *
class test_GUI:
def __init__(self):
fenster=Tk()
fenster.geometry("110x75")
#Die Listbox
lb = Listbox(fenster, selectmode=EXTENDED)
lb.pack()
lb.place(x=18, y=10, width=80, height=35)
lb.insert(END, "Peter")
lb.insert(END, "Hans")
#Der Button
test_button=Button(fenster,text="test", command=self.read)
test_button.place(x=6, y=50, width=100, height=20)
#die Methode
def read(event):
text = lb.get(lb.curselection())
print text
__name__ == '__main__'
dasFenster = test_GUI()
mainloop()
Code: Alles auswählen
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python25\lib\lib-tk\Tkinter.py", line 1403, in __call__
return self.func(*args)
File "C:\123.py", line 19, in read
text = lb.get(lb.curselection())
NameError: global name 'lb' is not defined
Vielleicht ist der Fehler zu einfach zu beheben, dass ich nicht drauf komme
Du musst lb an die Klasse binden mit dem Schlüsselwort self...
Also statt lb lieber self.lb, weil du es ja auch außerhalb der __init__ Methode benutzen willst.
Also statt lb lieber self.lb, weil du es ja auch außerhalb der __init__ Methode benutzen willst.
Wenn ich jedes lb mit'n self.lb ersetz und bei read natürlich noch das Argument self hinzukommt
Jedoch gibts dann noch Probleme mit dem Eventbinding und außerdem benutzt du einen außerordentlich bösen Sternimport. Mit self globalisierst du auch nicht, sondern bindest die Variable an die Instanz der Klasse.
(Ich würd' dir ja jetzt'n funktionierendes Beispiel geben, aber von Tkinter hab ich recht wenig Ahnung)
Code: Alles auswählen
def read(self, event):
text = self.lb.get(lb.curselection())
print text
(Ich würd' dir ja jetzt'n funktionierendes Beispiel geben, aber von Tkinter hab ich recht wenig Ahnung)
Was ist am Sternimport denn böse?
und deinen Lösungsansatz hatte ich auch schon eingeschlagen, aber:
und deinen Lösungsansatz hatte ich auch schon eingeschlagen, aber:
Code: Alles auswählen
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python25\lib\lib-tk\Tkinter.py", line 1403, in __call__
return self.func(*args)
TypeError: read() takes exactly 2 arguments (1 given)
Man überschreibt Schlüsselwörter, die Übersichtlichkeit geht flöten und der Quellcode wird unübersichtlicher. Hab'n bissel rumgespielt, ist sicherlich total schlechter tkinter Stil, jedoch funktioniert die Version...
(UM NOCHMAL DARAUF HINZUWEISEN!!! Ich bin kein Tkinter Programmierer. Der Quelltext stellt keine Referenz dar!)
(UM NOCHMAL DARAUF HINZUWEISEN!!! Ich bin kein Tkinter Programmierer. Der Quelltext stellt keine Referenz dar!)
Code: Alles auswählen
import Tkinter as tk
class test_GUI:
def __init__(self):
fenster = tk.Tk()
fenster.geometry("110x75")
#Die Listbox
self.lb = tk.Listbox(fenster, selectmode=tk.EXTENDED)
self.lb.pack()
self.lb.place(x=18, y=10, width=80, height=35)
self.lb.insert(tk.END, "Peter")
self.lb.insert(tk.END, "Hans")
#Der Button
test_button = tk.Button(fenster, text="test", command=self.read)
test_button.place(x=6, y=50, width=100, height=20)
#die Methode
def read(self):
for i in self.lb.curselection():
text = self.lb.get(i)
print text
__name__ == '__main__'
dasFenster = test_GUI()
tk.mainloop()
Vielleicht solltest Du Dich erst einmal nur mit Klassen, ohne GUI beschäftigen. Das erste Argument bei Methoden ist immer die Instanz auf der die Methode aufgerufen wird. Dein `event` ist also eigentlich `self` und beim Druck auf den den Button wird an die `command`-Funktion gar nichts übergeben.
Da sind so gut wie alle manuelle Grössenangaben herausgenommen, das kann der Layout-Manager im allgemeinen besser als der Programmierer, weil der ja gar nicht alle möglichen Schrifteinstellungen, Schriftgrössen und Windowmanager testen kann.
Die Grösse der `Listbox` sollte man auch dort beim Konstrukturaufruf angeben, weil die Höhe da z.B. in Zeilen/Einträgen angegeben wird. Das passt dann immer, im Gegensatz zu dem `place()` wo bei mir in der Anzeige der untere Rand vom zweiten Eintrag nicht mehr dargestellt wurde.
Code: Alles auswählen
import Tkinter as tk
class TestGUI:
def __init__(self):
fenster = tk.Tk()
self.listbox = tk.Listbox(fenster,
selectmode=tk.EXTENDED,
width=10,
height=2)
for name in ('Peter', 'Hans'):
self.listbox.insert(tk.END, name)
self.listbox.pack()
test_button = tk.Button(fenster, text='test', command=self.read)
test_button.pack()
def read(self):
print self.listbox.get(self.listbox.curselection())
if __name__ == '__main__':
das_fenster = TestGUI()
tk.mainloop()
Die Grösse der `Listbox` sollte man auch dort beim Konstrukturaufruf angeben, weil die Höhe da z.B. in Zeilen/Einträgen angegeben wird. Das passt dann immer, im Gegensatz zu dem `place()` wo bei mir in der Anzeige der untere Rand vom zweiten Eintrag nicht mehr dargestellt wurde.
Gut, das Globlisieren funktioniert jetzt einwandfrei vielen Dank nochmal an euch, das hat noch paar andere Fehler behoben.
Das einzige was jetzt noch fehlt ist der "Fokus" ich weiß nicht wie das sonst nennen soll Ich will einfach nur das die Auswahl in den Boxen bleibt und nicht verschwindet.
hier ein flash-Filmchen, damit ihr versteht was ich meine :
Klick mich zum Anschaun
ich find dazu auch nichts in keinem der offiziellen Tutorials
Das einzige was jetzt noch fehlt ist der "Fokus" ich weiß nicht wie das sonst nennen soll Ich will einfach nur das die Auswahl in den Boxen bleibt und nicht verschwindet.
hier ein flash-Filmchen, damit ihr versteht was ich meine :
Klick mich zum Anschaun
ich find dazu auch nichts in keinem der offiziellen Tutorials