ListboxWithScrollbar

Fragen zu Tkinter.
Antworten
Costi
User
Beiträge: 545
Registriert: Donnerstag 17. August 2006, 14:21

ich will ein objekt haben der sich genau wie eine Listbox anfuelt, in wirklichkeit aber eine listbox mit scrollbar ist.
habe es mit mit den unteren code versucht, klappt aber nicht. bitte klaert mich auf :-)

Code: Alles auswählen

class ListboxWithScrollbar(Listbox):
	def __init__(self, parent=None):
		self.frame = Frame(parent)
		Listbox.__init__(self, self.frame)
		self.pack(side=LEFT)
		scroll = Scrollbar(self.frame)
		scroll.pack(side=RIGHT, fill=Y)
		self['yscrollcommand'] = scroll.set
		scroll['command'] = self.yview
	def __getattr__(self, name):
		for i in ['pack', 'grid', 'place']:
			if name == i:
				return getattr(self.frame, i)
		return self
cp != mv
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

hallo,
vermutlich meinst du so was hier

Code: Alles auswählen

import Tkinter as tk 

class ListBoxer(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.pack(expand=tk.YES, fill=tk.BOTH)
        LB = tk.Listbox( self )
        LB.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
        SC = tk.Scrollbar(self)
        SC.pack(side=tk.RIGHT, fill=tk.Y)
        LB['yscrollcommand']=SC.set
        SC['command'] =LB.yview
        for i in range(100):
            LB.insert(tk.END, 'Hallo Python')
        
def _main():
    root = tk.Tk()
    listbox = ListBoxer(root)
   
    root.mainloop()
if __name__=='__main__':
    _main()
Redprince
User
Beiträge: 128
Registriert: Freitag 22. Oktober 2004, 09:22
Wohnort: Salzgitter
Kontaktdaten:

Das war auch meine erste Idee, jedoch hat die Listbox mit Scrollbar dann die Eigenschaften/Methoden von Tkinter.Frame und nicht (wie wohl geplant) von Tkinter.Listbox..
Ich sehe irgendwie noch nicht, warum der Ansatz von Costi nicht funktionieren will :roll:
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Hi!
Der Fehler liegt in Zeile 4: Da wird ein neues Frame erstellt, aber nicht gepackt.
So

Code: Alles auswählen

class ListboxWithScrollbar(Listbox): 
    def __init__(self, parent=None): 
        self.frame = parent
        Listbox.__init__(self, self.frame) 
        self.pack(side=LEFT) 
# ...
...oder so

Code: Alles auswählen

class ListboxWithScrollbar(Listbox): 
    def __init__(self, parent=None):
        self.frame = Frame(parent)
        self.frame.pack()
        Listbox.__init__(self, self.frame) 
#...
...gehts. :wink:

mfg, jj
Costi
User
Beiträge: 545
Registriert: Donnerstag 17. August 2006, 14:21

gepackt sollte er manuell werden:

Code: Alles auswählen

    def __getattr__(self, name):
        for i in ['pack', 'grid', 'place']:
            if name == i:
                return getattr(self.frame, i)
        return self 
der aufruf eines packers wird an das Frame weitergeleitet ( ;
cp != mv
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Ehm...wer ist er?
Und wenn er manuell gepackt werden sollte, wieso wird er es dann nicht?
Ich versteh deine __getattr__ nicht so ganz. Aber das klappt ja auch nicht. Und desswegen wolltest du doch einen Vorschlag, wie's geht. Also, wenn es bei dir jetzt noch nicht läuft, sehe ich 2 Möglichkeiten, die liefen:

1.) Du nimmst meinen ersten Vorschlag und packst alles in das Elternframe rein, was natürlich nicht so perfekt wäre;

2.) Du machst es so, dass du der __init__ direkt den Geomanager als Argument übergibst. Es ist ja nicht so, dass damit die listbox gepackt wird, sondern nur das Frame, was ja eigentlich keine auswirkungen hat.

Falls du deinen Uransatz doch noch zum Laufen krigst, zeig ihn mal.

Gruß, jj
Costi
User
Beiträge: 545
Registriert: Donnerstag 17. August 2006, 14:21

Falls du deinen Uransatz doch noch zum Laufen krigst, zeig ihn mal.

Code: Alles auswählen

>>> class ListboxWithScrollbar(Listbox):
	    def __init__(self, parent=None, **args):
	        self.frame = Frame(parent)
	        Listbox.__init__(self, self.frame, args)
	        self.pack(side=LEFT)
	        scroll = Scrollbar(self.frame)
	        scroll.pack(side=RIGHT, fill=Y)
	        self['yscrollcommand'] = scroll.set
	        scroll['command'] = self.yview
	        self.pack = self.frame.pack
	        self.place = self.frame.place
	        self.grid = self.frame.grid

	        
>>> lws = ListboxWithScrollbar(width=30)
>>> lws.pack()
cp != mv
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Ok, das geht auch.
Hat aber einen Haken die Sache: Erstens schließt du ´place´ aus, zweitens könnte es zu Problemen zwischen pack und grid kommen, da du die Listbox immer mit pack packst (pack und grid vertragen sich nicht so gut, wobei ich bei dem Fall jetzt keine Testreihe gemacht hab), und drittens, was ist mit Argumenten, die übergeben werden? Sowas wie ´expand´ bei pack muss schon bei frame und Listbox gesetzt werden, sonst bringt das nix. :wink:

Gruß, jj

:arrow: noch ein kleiner Pimptip: Wenn du das schon extra in eine eigene Klasse packst, kanns du auch noch ne Spaltenüberprüfung mit reinbauen, die die Scrollleiste je nach Bedarf ein- und ausblendet.
Antworten