OptionMenu - (zu) viele items

Fragen zu Tkinter.
Antworten
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

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
BlackJack

Scrollbalken in einem Menü ist ungewöhnlich. Kannst Du die vielen Einträge nicht irgendwie sinnvoll auf Untermenüs verteilen?
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

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
BlackJack

Psst: das ist das Tkinter-Forum. Hier ist ein OptionMenu ein Menübutton der neben dem Label auch eine Checkbox hat. :-)
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

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
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

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
Benutzeravatar
think
User
Beiträge: 37
Registriert: Donnerstag 22. Februar 2007, 10:02
Wohnort: Schweiz

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.
BlackJack

Mein Vorschlag bleibt trotzdem weiterhin eine feinere Aufteilung. Kann man die Gewässer nicht noch einmal in Gebiete aufteilen?
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

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
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

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
Zuletzt geändert von Mawilo am Dienstag 4. September 2007, 18:52, insgesamt 3-mal geändert.
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

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
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

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
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

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)
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

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
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

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
Zuletzt geändert von Mawilo am Dienstag 4. September 2007, 18:56, insgesamt 1-mal geändert.
Tux
User
Beiträge: 70
Registriert: Freitag 8. November 2002, 23:07
Kontaktdaten:

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
Antworten