Seite 1 von 1

OptionMenu - (zu) viele items

Verfasst: Donnerstag 22. Februar 2007, 08:29
von Tux
Hi @ll,

ich hab mal wieder n Problem, bei dem ich bisher keine Lösung gefunden hab:

Ich hab mit Tkinter ein OptionMenu erstellt. Dieses hat 50 items. Diese werden zwar alle angezeigt, aber die Leiste des Menüs geht über den ganzen Bildschirm.
Ich möchte diese Leiste verkleinern, sodass ich im Endeffekt immer 10 der 50 items sehe und den Rest dann mit ner Scrollbar erreiche.

Wie kann man das umsetzen?

Danke schonmal


MfG
Tux

Verfasst: Donnerstag 22. Februar 2007, 09:21
von BlackJack
Scrollbalken in einem Menü ist ungewöhnlich. Kannst Du die vielen Einträge nicht irgendwie sinnvoll auf Untermenüs verteilen?

Verfasst: Donnerstag 22. Februar 2007, 09:50
von rayo
Blackjack:
Ist ein OptionMenu nicht eine Select-Box im HTML? Also so ein Feld bei dem man ein Wert auswählen kann und ein Popupmenü mit den Auswahlen kommt, da ist es ja normal/üblich dass man bei vielen Werten einen Scrollbar bekommt.

Aber hab keine Ahnung wie das geht.

Gruss

Verfasst: Donnerstag 22. Februar 2007, 10:14
von BlackJack
Psst: das ist das Tkinter-Forum. Hier ist ein OptionMenu ein Menübutton der neben dem Label auch eine Checkbox hat. :-)

Verfasst: Donnerstag 22. Februar 2007, 10:41
von rayo
Hi

Also wenn ich sowas mache, sieht es nicht wie eine Checkbox aus sondern wie eine Selectbox.

Code: Alles auswählen

import Tkinter

r=Tkinter.Tk()

w = Tkinter.OptionMenu(r, Tkinter.StringVar(), "Eintrag 1", "Eintrag 2", "Eintrag 3")
w.pack()

r.mainloop()
Gruss

Verfasst: Donnerstag 22. Februar 2007, 10:45
von BlackJack
:oops: Peinlich… :oops:

Verfasst: Donnerstag 22. Februar 2007, 11:31
von Tux
Hallo nochmal,

schön, dass ihr euch mit meinem Problem befasst, aber nun fehlt leider noch die Lösung.

@BlackJack: So dumm es auch klingen mag: Das sind schon nur Teile des Menüs.
Als kleine Erklärung: Es soll ein Programm für den Anglerverband Thüringen werden und in diesem Menü soll man dann das betroffene Gewässer aussuchen können -- da gibt es nunmal einige... Weitere Untermenüs werden die Fische darin und noch eine Einteilung dieser Fische

Was ich haben möchte, sieht man ja auch in vielen anderen Programmen (einfaches Bsp. ist der Firefox -- die URL-Leiste kann man ja auch ausklappen und dort sieht man ja auch nur 20 der n gespeicherten Adressen, die man aufgerufen hat und den Rest kann man dann scrollen).

Wenn Python erkennt, dass es über den Bildschirm hinaus geht, macht er ja auch automatisch oben und unten einen Laufpfeil -- die würden mir ja auch reichen, aber es sieht nunmal nicht sonderlich toll aus, wenn das Menü über den ganzen Bildschirm geht.


Als Notvariante hab ich mir auch überlegt ne Listbox mit Scrollbar zu nehmen, aber ich fände es halt mit OptionMenü optisch besser...


Danke für eure Mühen
Tux

Verfasst: Donnerstag 22. Februar 2007, 11:40
von think
Hier, hatte einer das gleiche Problem wie du:
http://mail.python.org/pipermail/tkinte ... 00248.html
If this is true, there's probably no way to do what you ask. The Tk
Menu widget doesn't support scrolling, at least on Unix. On Windows,
the native menu control is be used, and that may or may not support
scrolling. I don't know the current state of affairs on OS X.

Verfasst: Donnerstag 22. Februar 2007, 15:08
von BlackJack
Mein Vorschlag bleibt trotzdem weiterhin eine feinere Aufteilung. Kann man die Gewässer nicht noch einmal in Gebiete aufteilen?

Verfasst: Donnerstag 22. Februar 2007, 16:04
von schlangenbeschwörer
Also wenn du es nicht weiter aufteilen willst, was ja am einfachsten wäre, sondern umbedingt alles untereinander zum scrollen brauchst, nimm doch ein Canvas. Du könntest es je nach Möglichkeiten im Hauptmenü in nem randlosen Toplevel aufrufen, was du dann noch richtig platzieren musst. In das Canvas plazierst du einfach alle deine Untermenüs untereinander, und mit ein bisschen Eventhandling lässt du es auch wieder passend verschwinden, wie ein normales Menü.
Und in einem Canvas kannst du die anderen Menübuttons besser anordnen, als in einer Listbox, dh es sähe vmt. besser aus, vlt. sogar fast wie ein normales Menü.
Gruß, jj

Verfasst: Donnerstag 22. Februar 2007, 18:13
von Mawilo
Versuche es doch einmal mit einer ComboBox von Tix. Dort kannst du die Auswahl scrollen, wenn zu viel Einträge drin stehen. Und unter Windows ist Tix schon mit dabei.

Hier ein kleines Beispiel:

Code: Alles auswählen

# -*- coding: iso-8859-15-*-

import Tix as tx     

root = tx.Tk()
l = tx.Label(root, text = 'Hier steht ein Text')
w = tx.ComboBox(root, editable=True)
w.insert(1, "Element1")
w.insert(2, "Element2")
w.insert(3, "Element3")
w.insert(4, "Element4")
w.insert(5, "Element5")
w.insert(6, "Element6")
w.insert(7, "Element7")
w.insert(8, "Element8")
w.insert(9, "Element9")
w.insert(10, "Element10")
w.insert(11, "Element11")
w.insert(12, "Element12")
w.insert(13, "Element13")
w.insert(14, "Element14")
w.insert(15, "Element15")
w.insert(16, "Element16")
w.insert(17, "Element17")
w.insert(18, "Element18")
w.insert(19, "Element19")
w.pack(side="right")
l.pack (side="left")

root.mainloop()
Und das kommt dabei raus:
Ansicht in Windows: Bild und für KDE: Bild

Eine Beschreibung zu Tix findest du hier.

Stephan

Verfasst: Freitag 23. Februar 2007, 07:25
von Tux
Super - danke für die ganze tollen Tipps

Die Gewässer in Gebiete aufzuteilen wäre sicherlich möglich, aber es wäre für die letztendliche Handhabung nicht sehr dienlich - ich weiß zwar von einigen Gewässern, dass es sie gibt und wie sie heißen, aber ich habe keine Ahnung wo sie sind.
Zumal von den Gewässern, die ich erst einmal einprogrammieren soll, alle im Raum Erfurt sind - wie soll ich da die Einteilung machen? Wenn dann später weitere Landkreise dazukommen, werde ich sicherlich noch nach den Vereinen oder Landkreisen aufteilen.

Die Idee mit dem Canvas klingt schonmal ganz gut (hab mich bisher nur wenig mit Canvas beschäftigt - muss dann halt mal schaun, ob ich das auf die Reihe bekomme)...

Wenn das mit dem Tix so funktioniert, wie ich mir das vorstelle, scheint mein Problem ja gelöst zu sein -- leider funktioniert auf dem Python Movable das Tix nicht so richtig, sodass ich es mir leider noch nicht testen konnte - hoffe aber, dass es dann nachher auf meinem Laptop läuft...


Danke nochmal -- habt mir sehr geholfen...
Tux

Verfasst: Freitag 23. Februar 2007, 14:41
von schlangenbeschwörer
Hi,
ich hätte da auchmal ein Codebeispiel, was nur mit Tkinter auskommt:

Code: Alles auswählen

import Tkinter as tk

class Example:
    def __init__(self):
        self.master=tk.Tk()
        self.menu=tk.Menu(self.master)
        self.master["menu"]=self.menu
        self.menu.add_command(label="scrollmenu",command=self.scrollmenu)
        self.master.bind_all("Any-ButtonPress",self.menuexit)
        self.text=tk.Text()
        self.text.pack()

    def scrollmenu(self):
        top=tk.Toplevel()
        top.overrideredirect(1)
        
        canvas=tk.Canvas(top,bg="white",width=75,height=100)
        canvas.pack(side="left")
        frame=tk.Frame(canvas)
        canvas.create_window(0,0,anchor="nw",window=frame)
        
        for i in range(10):
            b=tk.Menubutton(frame,text="menubutton",direction="right")
            b.pack(fill="x")
            submenu=tk.Menu(b,tearoff=0)
            for i2 in range(5):
                submenu.add_command(label="command%d"%i,command=self.doit)
            b["menu"]=submenu
            
        scroll=tk.Scrollbar(top,command=canvas.yview)
        scroll.pack(side="right",fill="y")
        canvas.config(scrollregion=(0,0,100,200),yscrollcommand=scroll.set)
        
        mastergeometry=self.master.geometry().replace("x","+").split("+")
        top.geometry("%dx%d+%d+%d"%(80,100,int(mastergeometry[2])+4,int(mastergeometry[3])+50))
        self.top=top

    def menuexit(self,event):
        self.top.destroy()
        
    def doit(self):
        pass

test=Example()
test.master.mainloop()
Gruß, jj

Verfasst: Sonntag 25. Februar 2007, 11:24
von Tux
Hi @ll,

um erst noch einmal auf die Lösung mit Tix zurückzukommen. Laut deiner Grafik siehts voll cool aus - das wärs! Hab den Quelltext mal kopiert und geschaut obs geht und hab folgenden Fehler erhalten:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:/Python25/tixtest.py", line 5, in <module>
    root = tx.Tk()
  File "C:\Python25\lib\lib-tk\Tix.py", line 210, in __init__
    self.tk.eval('package require Tix')
TclError: can't find package Tix
^^doof!
-import Tix funktioniert problemlos
-root = tx.Tk() <-- wenn der Rest auskommentiert ist, gibts dort den Fehler

-wenn ich das Tk mit Tkinter erzeuge, funktioniert das Label, aber bei der ComboBox gibts folgenden Fehler:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Python25\tixtest.py", line 7, in <module>
    w = tx.ComboBox(root, editable=True)
  File "C:\Python25\lib\lib-tk\Tix.py", line 576, in __init__
    cnf, kw)
  File "C:\Python25\lib\lib-tk\Tix.py", line 307, in __init__
    self.tk.call(widgetName, self._w, *extra)
TclError: invalid command name "tixComboBox"
@schlangenbeschwörer:
Deine Idee gefällt mir auch sehr gut - zumal sie auch auf Tkinter beruht. Müsste halt optisch dann in Kauf nehmen, dass es eigentlich ne Menüleiste ist.

Ich werd mal sehn, ob ich nicht doch noch das Tix zum Laufen bekomme - falls jemand ne Idee zu dem Fehler oben hat:
-das Programm wird nur unter Win genutzt...
-hab derzeitig Python 2.5 (überlege aber wieder aufs 2.4 zurück zu gehn - irgendwie macht das 2.5 ein paar seltsame Fehler, die ich nicht ganz verstehe und die ich beim 2.4 nich hatte)

Verfasst: Sonntag 25. Februar 2007, 12:13
von Mawilo
Ich habe den Code unter W2k mit Python 2.4 und unter Linux mit Python 2.5 getestet. Bei mir funktioniert es :D

Bekommst du auch eine Fehlermeldung, wenn du beides mit * importierst (und dann natürlich das tx. weglässt)?

Code: Alles auswählen

from Tkinter import *
from Tix import *
Stephan

Verfasst: Sonntag 25. Februar 2007, 13:44
von Mawilo
Ich habe es nun auch mal mit Python 2.5 getestet - mit dem gleichen Ergebnis wie du :( .

Das ist ein Bug in der Version 2.5 und soll mit der Version 2.5.1 gefixt werden (siehe hier).

Wenn du nicht so lange warten möchtest, kannst du den Fehler auch selbst beheben. Du musst nur das Verzeichnis C:\Python24\tcl\tix8.1 aus einer 2.4er Version in das Verzeichnis C:\Python25\tcl\ kopieren und die Datei C:\Python24\DLLs\tix8184 in das Verzeichnis C:\Python25\DLLs kopieren.

Falls du das Verzeichnis und die dll nicht hast, kannst du das Verzeichnis (gezipt) und die Datei tix8184.dll downloaden. Ich habe sie mal ins Netz gestellt.

Bei mir funktioniert damit Tix auch mit Python 2.5. Ich bekomme nur noch folgende Meldung:

Code: Alles auswählen

attempt to provide Tix 8.1 failed: package Tix 8.1.8.4 provided instead
Aber das geht bestimmt auch noch auszubügeln.

Stephan

Verfasst: Sonntag 25. Februar 2007, 14:57
von Tux
Hey danke Leute -- ihr seid die Besten :D

ich hab sowieso vor nächstes WE meinen Rechner mal wieder platt zu machen (hat halt n paar Macken und hochfahren dauert ewig etc. - die meisten werden wissen was ich meine) und dann mach ich erstmal die 2.4 wieder drauf --> hab ihr eigentlich 2.5 nur zum Austesten der neuen Features geholt und mit 2.4 bin ich auch immer gut klar gekommen. Wenns dort läuft, ists doch super...

Ich meld mich dann (über-)nächste Woche nochmal und schreib euch obs geklappt hat...

Grüßigkeiten
Tux