Ich habe bis jetzt erfolgreich eine Listbox erstellt, will durch diese aber nicht mit der Tastatur oder einer Maus Navigieren sondern mit einem Tochdisplay.
Dafür will ich 2 Buttons erstellen mit deren Hilfe ich den Aktiven Balken hoch und runter bewege, -> mit .curselection() dann die Position ermitteln, und einem dritten Button diesen dann auswählen.
Wie erstelle ich solche "NavigationsButtons"?
Danke schonmal
Hoch Runter Button für eine Listbox
@PappaBär83: Wo liegt denn das konkrete Problem dabei? Du musst halt Schaltflächen erstellen bei denen als `command` jeweils Funktionen/Methoden übergeben werden welche die entsprechenden Aktionen durchführen. Also beispielsweise für ”Selektion runter” die aktuelle Selektion ermitteln, löschen, und das darauffolgende Element auswählen. Ähnlich für ”Selektion rauf”. Dabei auch auf die Randfälle achten wie: Es war nichts ausgewählt, oder die Auswahl ist bereits am jeweiligen Rand (oben/unten). Man könnte so ein kombiniertes Bedienelement in einer eigenen Klasse kapseln.
-
- User
- Beiträge: 21
- Registriert: Freitag 5. September 2014, 09:16
Hey.
Ich kenne kein Kommando oder keine Methode mit der ich das machen kann.
Habe Probiert mit (Listboxname).curselection() versucht die aktuelle Markierte Position zu ermitteln, bei Drücken eines Buttons diesen Wert um 1 zu erhöhen oder herabzusetzen und diesen dann per (Listenname).select_set(Wert) zurückzugeben.
Das hat aber nicht funktioniert.
Nach Nachlesen fand ich heraus das .curselection() ein Tupel zurückgiebt und mit den kann man nicht rechnen,
Tupel in eine Zahl umwandeln hat auch nicht Funkioniert. (<- bei mir jedenfalls nicht).
Ich kenne kein Kommando oder keine Methode mit der ich das machen kann.
Habe Probiert mit (Listboxname).curselection() versucht die aktuelle Markierte Position zu ermitteln, bei Drücken eines Buttons diesen Wert um 1 zu erhöhen oder herabzusetzen und diesen dann per (Listenname).select_set(Wert) zurückzugeben.
Das hat aber nicht funktioniert.
Nach Nachlesen fand ich heraus das .curselection() ein Tupel zurückgiebt und mit den kann man nicht rechnen,
Tupel in eine Zahl umwandeln hat auch nicht Funkioniert. (<- bei mir jedenfalls nicht).
@PappaBär83: Ein Tupel in eine Zahl umwandeln funktioniert natürlich nicht, was sollte denn da auch als Zahl heraus kommen? Du kannst aber die Zahl die in dem Tupel als Element steckt, heraus holen. Und das solltest Du wissen und können bevor Du Dich mit objektorientierter Programmierung und GUIs beschäftigst, denn Tupel ist einer der Grunddatentypen von Python mit denen man umgehen können muss, die laufen einem oft über den Weg.
Hast Du das Tutorial in der Python-Dokumentation schon einmal durchgearbeitet?
Hast Du das Tutorial in der Python-Dokumentation schon einmal durchgearbeitet?
-
- User
- Beiträge: 21
- Registriert: Freitag 5. September 2014, 09:16
learning by doing
Ich will, und ich gebe mir Mühe.
Auch wenn ich viele Bücher und To-Do's durcharbeite sind das Wichtige Kleinigkeiten die allein vom lesen nicht im Kopf bleiben wollen.
@BlackJack: wie bekomm ich das element aus dem Tupel? Mit .pop() funktioniert's nicht (hab ich gerade ausprobiert).
Hier mal ein Beispiel wie ich mir das Vorstelle und wo ich nicht weiterkomme
Ich will, und ich gebe mir Mühe.
Auch wenn ich viele Bücher und To-Do's durcharbeite sind das Wichtige Kleinigkeiten die allein vom lesen nicht im Kopf bleiben wollen.
@BlackJack: wie bekomm ich das element aus dem Tupel? Mit .pop() funktioniert's nicht (hab ich gerade ausprobiert).
Hier mal ein Beispiel wie ich mir das Vorstelle und wo ich nicht weiterkomme
Code: Alles auswählen
# Hoch-Runter Button Test
import tkinter
import sys
#def hoch():
#???#
#???#
#def runter():
#???#
#???#
def ende ():
sys.exit(0)
main = tkinter.Tk()
main.geometry("450x200")
Liste = tkinter.Listbox(main)
Liste.insert("end", "Zeile 1")
Liste.insert("end", "Zeile 2")
Liste.insert("end", "Zeile 3")
Liste.insert("end", "Zeile 3")
Liste.insert("end", "Zeile 4")
Liste.insert("end", "Zeile 5")
Liste.insert("end", "Zeile 6")
Liste["height"] = 7 # Höhe des Textfeldes
Liste["width"] = 29 # Breite des Textfeldes
Liste["font"] = "MS 12" # Schriftart und Schriftgröße
Liste.select_set('0')
Liste.place(x=110, y=0, anchor="nw")
hButton = tkinter.Button(main) # Button für liste Hoch
hButton["text"] = "Hoch"
#hButton["command"] = hoch
hButton.place(x=0, y=00, anchor="nw")
rButton = tkinter.Button(main) # Button für liste Runter
rButton["text"] = "Runter"
#rButton["command"] = runter
rButton.place(x=0, y=30, anchor="nw")
# SchlussButton
eButton = tkinter.Button(main) # Button zum Fensster beenden
eButton["text"] = "Fenster aus"
eButton["command"] = ende
eButton.place(x=0, y=80, anchor="nw")
main.mainloop()
@PappaBär83: Hast Du das Tutorial in der Python-Dokumentation schon einmal durchgearbeitet? Vor allem das Kapitel zu Indexzugriff?PappaBär83 hat geschrieben:Mit .pop() funktioniert's nicht (hab ich gerade ausprobiert).
-
- User
- Beiträge: 21
- Registriert: Freitag 5. September 2014, 09:16
@Sirius3: ma kurz drüber geschlafen (mittagsschlaft) und auf manches kommt man dann selber.
wie ich an das Element komme hab ich jetzt.
Nun is ein neues Problem aufgetaucht: ich muss die Markierung (Liste.select_set()) zurücksetzten bevor ich sie neu setzte sonnst wird alles druchmarkiert.
wie ich an das Element komme hab ich jetzt.
Nun is ein neues Problem aufgetaucht: ich muss die Markierung (Liste.select_set()) zurücksetzten bevor ich sie neu setzte sonnst wird alles druchmarkiert.
Code: Alles auswählen
# Hoch-Runter Button Test
import tkinter
import sys
def hoch():
Poho = Liste.curselection() #Position hoch
print (Poho)
Poho1 = Poho[0]
print (Poho1)
Poho2 = Poho1 - 1
print (Poho2)
Liste.select_set(Poho2)
def runter():
Poru = Liste.curselection() #Position runter
print (Poru)
Poru1 = Poru[0]
print (Poru1)
Poru2 = Poru1 + 1
print (Poru2)
Liste.select_set(Poru2)
def ende (): # Funktion zum Fenster beenden
sys.exit(0)
main = tkinter.Tk()
main.geometry("450x200")
Liste = tkinter.Listbox(main)
Liste.insert("end", "Zeile 1")
Liste.insert("end", "Zeile 2")
Liste.insert("end", "Zeile 3")
Liste.insert("end", "Zeile 4")
Liste.insert("end", "Zeile 5")
Liste.insert("end", "Zeile 6")
Liste.insert("end", "Zeile 7")
Liste["selectmode"] = "singel"
Liste["height"] = 7 # Höhe des Textfeldes
Liste["width"] = 29 # Breite des Textfeldes
Liste["font"] = "MS 12" # Schriftart und Schriftgröße
Liste.select_set(first = 4)
Liste.place(x=110, y=0, anchor="nw")
hButton = tkinter.Button(main) # Button für liste Hoch
hButton["text"] = "Hoch"
hButton["command"] = hoch
hButton.place(x=0, y=00, anchor="nw")
rButton = tkinter.Button(main) # Button für liste Runter
rButton["text"] = "Runter"
rButton["command"] = runter
rButton.place(x=0, y=30, anchor="nw")
# SchlussButton
eButton = tkinter.Button(main) # Button zum Fensster beenden
eButton["text"] = "Fenster aus"
eButton["command"] = ende
eButton.place(x=0, y=80, anchor="nw") # Button bei Pixel X=1 Y=600 Plazieren
main.mainloop()
@PappaBär83: Ich sehe da noch viel drängendere Probleme die man vorher angehen sollte. Zum Beispiel das Du Dich erst einmal mit objektorientierter Programmierung vertraut machen solltest statt ein Programm zu schreiben bei dem alles global auf Modulebene existiert. Das wird sehr schnell sehr unübersichtlich und fehleranfällig. Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm gehört in eine Funktion, die heisst üblicherweise `main()`. Und Werte (ausser Konstanten) sollten Funktionen und Methoden als Argumente betreten und nicht auf magische Weise einfach so in der Umgebung/auf Modulebene existieren.
Die Namensgebung ist teilweise sehr schlecht und hält sich in der Schreibweise nicht an den
Style Guide for Python Code. Namen sollen dem Leser vermitteln was der Wert der hinter dem Namen steckt im Kontext des Programms bedeutet. Namen wie `Poho`, `Poho1`, `Poho2`, `Poru`, `Poru1`, oder `Poru2` sind alles andere als selbsterklärend.
Anzeigeelemente mit `place()` absolut zu positionieren ist keine gute Idee. Das sieht dann nur auf Rechnern mit ähnlichen Einstellung wie dem auf dem es entwickelt wurde vernünftig aus und kann bei anderen Displays, Auflösungen, Grundeinstellungen des Systems, schlecht aussehen, oder sogar unbenutzbar werden.
Die Namensgebung ist teilweise sehr schlecht und hält sich in der Schreibweise nicht an den
Style Guide for Python Code. Namen sollen dem Leser vermitteln was der Wert der hinter dem Namen steckt im Kontext des Programms bedeutet. Namen wie `Poho`, `Poho1`, `Poho2`, `Poru`, `Poru1`, oder `Poru2` sind alles andere als selbsterklärend.
Anzeigeelemente mit `place()` absolut zu positionieren ist keine gute Idee. Das sieht dann nur auf Rechnern mit ähnlichen Einstellung wie dem auf dem es entwickelt wurde vernünftig aus und kann bei anderen Displays, Auflösungen, Grundeinstellungen des Systems, schlecht aussehen, oder sogar unbenutzbar werden.
-
- User
- Beiträge: 21
- Registriert: Freitag 5. September 2014, 09:16
Vielen dank für deine ausführliche Erläuterung warum ich hier nicht richtig bin.
Neben Beruf, Frau, Kindern und dem alltäglichen Schwachsinn des Alltags hatte ich vor mal was anders zu machen um den Kopf vom Normalstress abzulenken.
Hier bekommen anscheinend nur Studierte und Gelernte Programmiere direkte Antworten die zur Fragestellung passen.
Danke für eure Bemühungen.
Bücher können nur zeigen wie es aussehen sollte, aber keine Antworten geben wenn es mal nicht läuft.
Neben Beruf, Frau, Kindern und dem alltäglichen Schwachsinn des Alltags hatte ich vor mal was anders zu machen um den Kopf vom Normalstress abzulenken.
Hier bekommen anscheinend nur Studierte und Gelernte Programmiere direkte Antworten die zur Fragestellung passen.
Danke für eure Bemühungen.
Bücher können nur zeigen wie es aussehen sollte, aber keine Antworten geben wenn es mal nicht läuft.
@PappaBär83: Was war denn die konkrete Fragestellung im letzten Beitrag? Was Du machen musst hast Du ja selbst erkannt.
Hi PappaBär83
Hier ein Prototyp zum herumexperimentieren:An Stelle des Place-Layoutmanagers würde ich nur den Pack- oder Grid-Layoutmanager verwenden.
Gruss wuf
Hier ein Prototyp zum herumexperimentieren:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from functools import partial
try:
# Tkinter for Python 2.xx
import Tkinter as tk
except:
# Tkinter for Python 3.xx
import tkinter as tk
LISTBOX_HEIGHT = 10
LISTBOX_WIDTH = 29
LISTBOX_FONT = ('Helvetica', 12, 'normal')
LISTBOX_ITEMS = (
"Zeile 1",
"Zeile 2",
"Zeile 3",
"Zeile 4",
"Zeile 5",
"Zeile 6",
"Zeile 7",
"Zeile 8"
)
NUM_OF_ITEMS = len(LISTBOX_ITEMS)
BUTTON_UP = "Hoch"
BUTTON_DOWN = "Runter"
BUTTON_SELECT = "Selektiere"
BUTTON_READ_SELECTION = "Zeige Selektion"
BUTTON_CLEAR_SELECTION = "Lösche Selektion"
BUTTON_END = "Beenden"
BUTTON_CLOSE = "Schliessen"
BUTTONS = (BUTTON_UP, BUTTON_DOWN, BUTTON_SELECT, BUTTON_READ_SELECTION,
BUTTON_CLEAR_SELECTION, BUTTON_END)
DISPLAY_FONT = ('Helvetica', 14, 'bold')
DISPLAY_FG = 'steelblue'
class MyListbox(tk.Listbox):
def __init__(self, parent, **options):
self.parent = parent
tk.Listbox.__init__(self, parent, **options)
self.cursor_index = 0
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_cursor(self.cursor_index)
def set_cursor(self, index):
self.focus_set()
self.activate(index)
self.cursor_index = index
def select_item(self):
self.select_set(self.cursor_index)
def clear_selection(self):
self.selection_clear(0, 'end')
class Application(object):
def __init__(self, title=''):
self.main = tk.Tk()
self.main.title(title)
self.main.protocol("WM_DELETE_WINDOW", self.close)
main_frame = tk.Frame(self.main)
main_frame.pack(expand=True, padx=6, pady=6)
button_frame = tk.Frame(main_frame)
button_frame.pack(side='left', expand=True, padx=(0, 4))
listbox_frame = tk.Frame(main_frame, bd=0, relief='sunken')
listbox_frame.pack(side='left', expand=True, padx=(0, 4))
display_frame = tk.Frame(main_frame, bd=0, relief='sunken')
display_frame.pack(side='left', expand=True)
for button in BUTTONS:
tk.Button(button_frame, text=button, command=partial(
self.buttons_callback, button)).pack(fill='x')
self.my_listbox = MyListbox(listbox_frame, height=LISTBOX_HEIGHT,
width=LISTBOX_WIDTH, font=LISTBOX_FONT, highlightthickness=0,
bd=0)
self.my_listbox.pack(padx=4, pady=4)
listbox_frame.config(bg=self.my_listbox['bg'])
self.my_listbox.insert(0, *LISTBOX_ITEMS)
self.my_listbox.set_cursor(4)
self.display_var = tk.StringVar()
self.display_label = tk.Label(display_frame, height=LISTBOX_HEIGHT,
width=LISTBOX_WIDTH, textvariable=self.display_var, bd=0,
font=DISPLAY_FONT)
self.display_label.pack(padx=4, pady=4)
def buttons_callback(self, button):
print(button)
if button == BUTTON_END:
self.close()
if button == BUTTON_UP:
self.my_listbox.cursor_up()
if button == BUTTON_DOWN:
self.my_listbox.cursor_down()
if button == BUTTON_SELECT:
self.my_listbox.select_item()
if button == BUTTON_CLEAR_SELECTION:
self.my_listbox.selection_clear(0, 'end')
if button == BUTTON_READ_SELECTION:
selected_items = ''
for index in self.my_listbox.curselection():
selected_items += "{}\n".format(self.my_listbox.get(index))
#print(selected_items)
if selected_items != '':
self.display_var.set(selected_items)
def run(self):
self.main.mainloop()
def close(self):
# Here you can do something before shutdown!
self.main.destroy()
Application("Meine Auswahlliste").run()
Gruss wuf
Take it easy Mates!
Hierbei habe ich versucht das Kernproblem von dir, Papabär83, zu erfassen und die Lösung auf das notwendige Minimum zu reduzieren (wufs Zeilenzahl halbiert). Allerdings bleibt eine Kernaussage bestehen, welche Du in beiden Beispielen findest: Um die Verwendung von Klassen (Objektorientierte Programmierung, Vererbung) kommst Du nicht herum, wenn Du mit Tkinter (und allen anderen GUI-Toolkits) die Übersicht behalten willst.
Darüber hinaus existiert bis auf die Bedingung im "Main-Idiom" kein Code auf Modulebene. Das "Skript" ließe sich so zum Testen einzelner Funktionen aber auch zum Wiederverwerten ohne Seiteneffekte importieren. Das Grundgerüst für Deine Programme sollte in Zukunft so aussehen:
Ich weiß, dass viele tkinter-Beispiele, welche man im Netz finden kann, hierauf aus Gründen der "Einfachheit" verzichten. Aber wie gesagt, man erhält die Möglichkeit des interaktiven Testens (im Interpreter). Im folgenden Beispiel ließe sich die ints-Funktion im Interpreter testen, ohne dass ein Fenster erzeugt wird oder man das Programm im Ganzen starten müsste.
Im Komplettbeispiel wirst Du neben der Verwendung von Klassen, Dinge finden, welche neu für Dich wären:
Darüber hinaus existiert bis auf die Bedingung im "Main-Idiom" kein Code auf Modulebene. Das "Skript" ließe sich so zum Testen einzelner Funktionen aber auch zum Wiederverwerten ohne Seiteneffekte importieren. Das Grundgerüst für Deine Programme sollte in Zukunft so aussehen:
Code: Alles auswählen
#!/usr/bin/env python3
# Constants(!) go here
# Class and function-definitions go here
def main():
pass # Usefull code goes here
if __name__ == '__main__':
main()
Im Komplettbeispiel wirst Du neben der Verwendung von Klassen, Dinge finden, welche neu für Dich wären:
- Einen Generatorausdruck (ließe sich auch durch eine so genannte List-Comprehension (LC) formulieren) beim Einfügen der Beispielelement in die Listbox.
- Listenoperation map. Da Listen elementarer Sprachbestandteil von Python sind, bist Du gut beraten Dich eher früher als später mit ihnen zu beschäftigen. Sie erleichtern das Programmiererleben ungemein.
Code: Alles auswählen
#!/usr/bin/env python3
import sys
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master):
super().__init__(master)
self.listbox = None # tk.Listbox
self._init_widgets()
def _init_widgets(self):
# Listbox
self.listbox = tk.Listbox(self, selectmode=tk.SINGLE)
self.listbox.insert('end', *('Zeile {}'.format(e) for e in range(7)))
self.listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.listbox.select_set(0)
# Buttons
up = tk.Button(self, text='nach oben', command=self.selection_up)
up.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
down = tk.Button(self, text='nach unten', command=self.selection_down)
down.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
quit = tk.Button(self, text='Beenden', command=self.quit)
quit.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
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)
def quit(self):
sys.exit(0)
# -----------------------------------------------------------------------------
# Utility functions
# -----------------------------------------------------------------------------
def ints(xs):
"""Converts the values from ``xs`` into a list of integers (if possible)."""
return list(map(int, xs))
def first_selection(listbox):
"""Returns the index of the first selected item of a listbox or None."""
indices = ints(listbox.curselection())
if not indices: # Nothing selected
return
return indices[0]
# -----------------------------------------------------------------------------
# Main idiom
# -----------------------------------------------------------------------------
def main():
root = tk.Tk()
frame = Application(root)
frame.pack(fill=tk.BOTH, expand=True)
root.mainloop()
if __name__ == '__main__':
main()
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Hi Papabär83
Hierbei habe ich bwbg's Lösung auf das notwendige Minimum reduziert (bwg's Zeilenzahl 70 wuf's 45):
Gruss wuf
Hierbei habe ich bwbg's Lösung auf das notwendige Minimum reduziert (bwg's Zeilenzahl 70 wuf's 45):
Code: Alles auswählen
#!/usr/bin/env python3
import sys
import tkinter as tk
from functools import partial
BUTTONS = ('nach oben', 'nach unten', 'Beenden')
ITEMS = ('Zeile {}'.format(e) for e in range(7))
BUT_PROPS = dict(side=tk.TOP, fill=tk.BOTH, expand=True)
class Application(tk.Frame):
def __init__(self, master):
super().__init__(master)
self.listbox = tk.Listbox(self, selectmode=tk.SINGLE)
self.listbox.insert('end', *ITEMS)
self.listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.listbox.select_set(0)
[tk.Button(self, text=button, command=partial(self.callback, button)
).pack(BUT_PROPS) for button in BUTTONS]
def callback(self, button):
if button == 'Beenden': sys.exit(0)
else:
self.selection(button)
def selection(self, direction):
indices = self.listbox.curselection()
if not indices: return
index = indices[0]
if direction == 'nach oben':
if index == 0: return
self.listbox.select_clear(index)
self.listbox.select_set(index - 1)
if direction == 'nach unten':
if index >= self.listbox.size() - 1: return
self.listbox.select_clear(index)
self.listbox.select_set(index + 1)
def main():
root = tk.Tk()
frame = Application(root).pack(fill=tk.BOTH, expand=True)
root.mainloop()
if __name__ == '__main__': main()
Take it easy Mates!
Dass das mal nicht in code-golfing ausartet
Auf partial hatte ich ganz bewusst verzichtet. Aber lassen wir das jetzt mal so stehen, bevor die Verwirrung zu groß wird.
Auf partial hatte ich ganz bewusst verzichtet. Aber lassen wir das jetzt mal so stehen, bevor die Verwirrung zu groß wird.
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
@wuf: Etwas kürzer ohne ”schmutzige” Tricks wie LCs als Schleifenersatz und von der Formatierung her auch mehr nach dem Styleguide, also nicht auf biegen und brechen auf kurz getrimmt :
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)
pack_arguments = dict(side=tk.TOP, fill=tk.BOTH, expand=True)
tk.Button(
self, text='nach oben', command=partial(self.move_selection, -1)
).pack(pack_arguments)
tk.Button(
self, text='nach unten', command=partial(self.move_selection, 1)
).pack(pack_arguments)
tk.Button(self, text='Beenden', command=self.quit).pack(pack_arguments)
def move_selection(self, amount):
try:
index = int(self.listbox.curselection()[0])
except IndexError:
index = 0
self.listbox.select_clear(index)
self.listbox.select_set(
max(0, min(index + amount, self.listbox.size() - 1))
)
def main():
root = tk.Tk()
frame = Application(root)
frame.pack(fill=tk.BOTH, expand=True)
root.mainloop()
if __name__ == '__main__':
main()
Hi BlackJack
Super Code!
Hier mein Skript ohne die eher "schmutzige" LC als Schleifenersatz. Habe mein Skript noch einmal überarbeitet aber ohne den Einsatz deiner try:... except: Variante:N.B: Hoffen wir, dass unser Mittspieler PappaBär83 wieder in das Golf-Clubhaus zurückkehrt.
Gruss wuf
Super Code!
Willkommen im Club der Golferbwbg hat geschrieben:code-golfing
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()
Gruss wuf
Take it easy Mates!
@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.
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.
OK BlackJack
Besten Dank für deine Anregungen. Habe mein Skript noch ein weiteres mal angepasst:
Gruss wuf
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()
Take it easy Mates!
-
- 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
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
-
- 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!?!?
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!?!?