Seite 1 von 1
Problem: tk.Listbox() Auswahl bekommen...
Verfasst: Dienstag 11. November 2008, 18:37
von jens
Möchte das Ergebnis einer tk.Listbox Selektion abfragen, doch
listbox.curselection() spuckt einen Fehler aus. Was mache ich falsch?
Code: Alles auswählen
import sys
import Tkinter as tk
streams_txt = ["eins", "zwei", "drei"]
root = tk.Tk()
listbox = tk.Listbox(
root, selectmode=tk.MULTIPLE, height=len(streams_txt)
)
listbox.pack()
for txt in sorted(streams_txt):
listbox.insert(tk.END, txt)
tk.Button(root, text = "OK", command=root.destroy).pack(side=tk.RIGHT)
tk.Button(root, text = "Abort", command=sys.exit).pack(side=tk.RIGHT)
tk.mainloop()
print listbox.curselection()
Problem:
Code: Alles auswählen
Traceback (most recent call last):
File "test.py", line 21, in <module>
print listbox.curselection()
File "C:\Python25\lib\lib-tk\Tkinter.py", line 2489, in curselection
self._w, 'curselection'))
_tkinter.TclError: invalid command name ".41189504"
Verfasst: Dienstag 11. November 2008, 18:54
von numerix
Es dürfte daran liegen, dass du die tk-Instanz beim Klick auf [OK] zerstörst, bevor du die Methode curselection() aufrufst.
So funktioniert es:
Code: Alles auswählen
import sys
import Tkinter as tk
streams_txt = ["eins", "zwei", "drei"]
def output():
print listbox.curselection()
root = tk.Tk()
listbox = tk.Listbox(root, selectmode=tk.MULTIPLE, height=len(streams_txt))
listbox.pack()
for txt in sorted(streams_txt):
listbox.insert(tk.END, txt)
tk.Button(root, text = "OK", command=output).pack(side=tk.RIGHT)
tk.Button(root, text = "Abort", command=sys.exit).pack(side=tk.RIGHT)
tk.mainloop()
Verfasst: Dienstag 11. November 2008, 21:18
von abgdf
Hallo jens,
da bei Events wie Klicks auf Buttons Funktionen aufgerufen werden, in denen man in der Regel wieder auf die Fensterelemente zugreifen möchte, formuliert man Tkinter-GUIs auch am besten in einer Klasse. Das kann dann z.B. so aussehen:
Code: Alles auswählen
#!/usr/bin/env python
import Tkinter as tk
from Tkconstants import *
class MyApp:
def __init__(self):
self.streams_txt = ["eins", "zwei", "drei"]
self.root = tk.Tk()
self.listbox = tk.Listbox(self.root,
selectmode = tk.MULTIPLE,
height = len(self.streams_txt))
self.listbox.pack()
for txt in sorted(self.streams_txt):
self.listbox.insert(tk.END, txt)
self.but1 = tk.Button(self.root,
text = "OK",
command = self.showit)
self.but1.pack(side = RIGHT)
self.but2 = tk.Button(self.root,
text = "Abort",
command = self.root.destroy)
self.but2.pack(side = RIGHT)
# "RIGHT" kommt aus dem Modul "Tkconstants".
self.root.mainloop()
def showit(self):
print self.listbox.curselection()
if __name__ == "__main__":
app = MyApp()
Zum Beenden nimmt man lieber die ".destroy()"-Methode des Hauptfensterwidgets (hier self.root) als "sys.exit()", da dadurch Aufräumarbeiten besser erledigt werden.
Viele Grüße
Verfasst: Mittwoch 12. November 2008, 09:47
von jens
Das ist ja doof
Im Grunde möchte ich keine echte GUI Anwendung bauen, sondern viel mehr ein kleines Konsolenskript erweitern. Denn per Konsole kann man schlecht einem User ein Menü bauen, bei dem ehr mehrere Punkte auswählen kann. (Zumindest nicht unter Windows).
Aber danke für die Hinweise. Ich denke dann werde ich eine kleine Klasse bauen

Verfasst: Mittwoch 12. November 2008, 16:29
von abgdf
Ach so, sowas wie "Kommander" unter Linux? Vielleicht was Windows-spezifisches benutzen,
http://martin.hinner.info/apicmndr/
Aber es wäre vielleicht auch mit Tkinter möglich: In der Methode mit einem "os.system()" das Programm aufrufen, und dann ".destroy()" aufrufen.
Gruß
Edit: Oder geht es nicht um zu öffnende Programme, sondern um Werte, die im .bat-Skript weiterverarbeitet werden sollen?
Verfasst: Freitag 14. November 2008, 13:06
von jens
Meine Lösung schaut nun so aus:
Code: Alles auswählen
# -*- coding: utf-8 -*-
import sys
import Tkinter as tk
class TkListebox(object):
def __init__(self, title, lable, items, selectmode=tk.MULTIPLE, width=100):
self.selection = []
self.items = items
self.root = tk.Tk()
self.root.title(title)
tk.Label(self.root, text=lable, font = "Tahoma 9 bold").pack()
self.listbox = tk.Listbox(
self.root, selectmode=selectmode, height=len(items), width=width
)
self.listbox.pack()
vars = []
for txt in self.items:
self.listbox.insert(tk.END, txt)
b = tk.Button(self.root, text = "OK", command=self.save_selection)
b.pack(side=tk.RIGHT)
b = tk.Button(self.root, text = "Abort", command=sys.exit)
b.pack(side=tk.RIGHT)
tk.mainloop()
def save_selection(self):
self.selection = []
for index in self.listbox.curselection():
self.selection.append(self.items[int(index)])
self.root.destroy()
# Bsp:
streams_txt = ["eins", "zwei", "drei"]
selection = TkListebox(
title = "Please select",
lable = "Please select streams:",
items = streams_txt
).selection
print "Selection:", selection