Hoch Runter Button für eine Listbox

Fragen zu Tkinter.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi BlackJack

Super Code!
bwbg hat geschrieben:code-golfing
Willkommen im Club der Golfer :)

Hier mein Skript ohne die eher "schmutzige" LC als Schleifenersatz. Habe mein Skript noch einmal überarbeitet aber ohne den Einsatz deiner try:... except: Variante:

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk
from functools import partial

 
class Application(object):

    def __init__(self, root):
        self.listbox = tk.Listbox(root, selectmode=tk.SINGLE)
        self.listbox.insert(tk.END, *('Zeile {}'.format(i) for i in range(7)))
        self.listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        self.listbox.select_set(0)
        for button in ('nach oben', 'nach unten', 'Beenden'):
            tk.Button(root, text=button, command=partial(self.callback, button)
                ).pack(side=tk.TOP, fill=tk.BOTH, expand=True)

    def callback(self, button):
        if button == 'Beenden': quit()
        if button == 'nach oben': self.move_selection(-1)
        if button == 'nach unten': self.move_selection(1)

    def move_selection(self, displacement):
        indices = self.listbox.curselection()
        if not indices: return
        index = indices[0]
        if 0 <= index + displacement < self.listbox.size():
            self.listbox.select_clear(index)
            if displacement: self.listbox.select_set(index + displacement)
            if not displacement: self.listbox.select_set(index + 1) 

 
def main():
    root = tk.Tk()
    Application(root)
    root.mainloop()
 
 
if __name__ == '__main__':
    main()
N.B: Hoffen wir, dass unser Mittspieler PappaBär83 wieder in das Golf-Clubhaus zurückkehrt.

Gruss wuf :wink:
Take it easy Mates!
BlackJack

@wuf: So eine Dispatch-Methode mit vielen ``if``\s ist aus OOP-Sicht eher unschön. Das ist eine unnötige Indirektion über Zeichenketten statt direkt Funktionen/Methoden oder allgemeiner ausgedrückt passende aufrufbare Objekte als `command` zu verwenden. Wenn man bei der Schleife bleiben möchte kann man da ja über (Schaltflächenbeschriftung, `command`-Wert)-Paare iterieren und sich damit den Umweg über `callback()` sparen.

Du verwendest übrigens das ”falsche” `quit()`, nämlich das auf Modulebene aus den eingebauten Funktionen was es ausserhalb einer interaktiven Python-Shell eigentlich gar nicht geben dürfte. Passender wäre das auf dem Widget das den Abbruch der Tk-Hauptschleife und damit die Rückkehr vom `mainloop()`-Aufruf bewirkt.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

OK BlackJack

Besten Dank für deine Anregungen. Habe mein Skript noch ein weiteres mal angepasst:

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk
from functools import partial

 
class Application(tk.Frame):

    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.listbox = tk.Listbox(self, selectmode=tk.SINGLE)
        self.listbox.insert(tk.END, *('Zeile {}'.format(i) for i in range(7)))
        self.listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        self.listbox.select_set(0)
        for button, callback in (('nach oben', partial(self.move_sel, -1)), 
            ('nach unten', partial(self.move_sel, 1)), ('Beenden', self.quit)):
            tk.Button(self, text=button, command=callback).pack(
                side=tk.TOP, fill=tk.BOTH, expand=True)

    def move_sel(self, displacement):
        indices = self.listbox.curselection()
        if not indices: return
        index = indices[0]
        if 0 <= index + displacement < self.listbox.size():
            self.listbox.select_clear(index)
            self.listbox.select_set(index + displacement) 

 
def main():
    root = tk.Tk()
    frame = Application(root)
    frame.pack(fill=tk.BOTH, expand=True)
    root.mainloop()
 
 
if __name__ == '__main__':
    main()
Gruss wuf :wink:
Take it easy Mates!
PappaBär83
User
Beiträge: 21
Registriert: Freitag 5. September 2014, 09:16

So. Urlaub zu ende.
kam ja doch noch was zusammen ;) .
Ich glaub das was ich gesucht habe haben bwbg und wuf gefunden.
"
def cursor_up(self):
if self.cursor_index > 0:
self.cursor_index -= 1
self.set_cursor(self.cursor_index)

def cursor_down(self):
if self.cursor_index < NUM_OF_ITEMS - 1:
self.cursor_index += 1
self.set
"
"
def selection_up(self):
index = first_selection(self.listbox)
if not index:
# No selection (None) or index == 0 (evaluate to False)
return
self.listbox.select_clear(index)
self.listbox.select_set(index - 1)

def selection_down(self):
index = first_selection(self.listbox)
if index is None or index >= (self.listbox.size() - 1):
# No selection (None) or selected item is last item.
return
self.listbox.select_clear(index)
self.listbox.select_set(index + 1)
"

Das werde ich bei nächstbietender Gelegenheit mal ausprobieren.
Fettes Mercy
PappaBär83
User
Beiträge: 21
Registriert: Freitag 5. September 2014, 09:16

Jap
Da kann ich definitiv noch von lernen.
Wo komm ich eigentlich am besten weiter wenn ich mich über die Möglichkeiten (Argumente) von Funktionen belesen möchte?
Irgendwo müssen ja die vordefinierten Funktionen (wie Listbox) Dokumentiert sein!?!?
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi PappaBär83

Schau dir einmal diese beiden Links an. Zwar in english aber sehr umfangreich:
a) http://infohost.nmt.edu/tcc/help/pubs/t ... index.html
b) http://effbot.org/tkinterbook/

Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Ich wiederhole mich immer gerne. Neben den Tutorials, Büchern nutze den interaktiven Interpreter!

Gekürztes Beispiel an der Listbox-Klasse:

Code: Alles auswählen

>>> import tkinter
>>> dir(tkinter.Listbox)
['_Misc__winfo_getint', [...], 'select_clear', 'select_includes', 'select_set', 'sele
ction_anchor', 'selection_clear', 'selection_get', 'selection_handle', 'selectio
n_includes', 'selection_own', 'selection_own_get', 'selection_set', 'send', 'set
var', 'size', 'slaves', 'tk_bisque', 'tk_focusFollowsMouse', 'tk_focusNext', 'tk
_focusPrev', 'tk_menuBar', 'tk_setPalette', 'tk_strictMotif', 'tkraise', 'unbind
', 'unbind_all', 'unbind_class', 'update', 'update_idletasks', 'wait_variable',
'wait_visibility', 'wait_window', 'waitvar', 'winfo_atom', [...], 'yview_scroll']
>>> help(tkinter.Listbox.size)
Help on function size in module tkinter:

size(self)
    Return the number of elements in the listbox.

>>>
Das hilft insofern weiter, als dass Tutorials nie den kompletten Umfang abbilden können. Man muss natürlich wissen was man sucht, aber das Finden der Richtigen Stichworte entwickelt sich mit den Jahren/Erfahrung.

Und bitte in Zukunft die Code-Tags verwenden.
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
PappaBär83
User
Beiträge: 21
Registriert: Freitag 5. September 2014, 09:16

:D
Dankt euch @bwbg und @wuf das wird mir sehr weiterhelfen.
Antworten