Wie bekommt man die Anzahl der Menüeinträge heraus?

Fragen zu Tkinter.
Antworten
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Ich möchte bei Menüs die Anzahl der Menüeinträge herausfinden. Wie geht das? Zum Beispiel hier:

Code: Alles auswählen

# -*- coding: utf-8 -*-

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk

class Application(tk.Tk):

    def __init__(self,**kwargs):
        tk.Tk.__init__(self,**kwargs)
        # widget definitions ===================================
        self.menu = Menu_1(self)
        self['menu'] = self.menu

class Menu_1(tk.Menu):

    def __init__(self,master,**kwargs):
        tk.Menu.__init__(self,master,**kwargs)
        # widget definitions ===================================
        self.add_command(label='command')
        self.add_checkbutton(label='checkbutton')
        self.add_radiobutton(value='radiobutton', label='radiobutton')
        self.count_menu_items()

    def count_menu_items(self):
        x = -1 # ???
        print('how many: {}'.format(x))


if __name__ == '__main__':
    Application().mainloop()
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Alfons

Was hältst du von dieser Lösung?:

Code: Alles auswählen

    def count_menu_items(self):
        x = self.index(tk.END) #-1 # ???
        print('how many: {}'.format(x))
Gruss wuf :wink:
Take it easy Mates!
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

wuf hat geschrieben:Hi Alfons

Was hältst du von dieser Lösung?:

Code: Alles auswählen

    def count_menu_items(self):
        x = self.index(tk.END) #-1 # ???
        print('how many: {}'.format(x))
Gruss wuf :wink:
Hi wuf, Du bst der Experte der sich auskennt. Mir ist kurz danach auch die Lösung eingefallen. Zuerst hatte ich als index einfach 1000 genommen statt tk.End. Doch dann ist mir eingefallen, dass auch 'end', oder wie Du geschrieben hattest tk.END gehen sollte

Aber Du hast auch etwas Wichtiges vergessen. Deine Lösung ist mathematisch nicht ganz richtig, denn hier werden nur zwei Menu items ausgegeben:

Code: Alles auswählen

# -*- coding: utf-8 -*-

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk

class Application(tk.Tk):

    def __init__(self,**kwargs):
        tk.Tk.__init__(self,**kwargs)
        # widget definitions ===================================
        self.menu = Menu_1(self,tearoff=0)
        self['menu'] = self.menu

class Menu_1(tk.Menu):

    def __init__(self,master,**kwargs):
        tk.Menu.__init__(self,master,**kwargs)
        # widget definitions ===================================
        self.add_command(label='command')
        self.add_checkbutton(label='checkbutton')
        self.add_radiobutton(value='radiobutton', label='radiobutton')
        self.count_menu_items()

    def count_menu_items(self):
        x = self.index(tk.END) #-1 # ???
        print('how many: {}'.format(x))
 
if __name__ == '__main__':
    Application().mainloop()
Aber das stimmt doch nicht, oder?
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Alfons

Hier noch eine Lösung:

Code: Alles auswählen

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
 
try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk


class Application(tk.Tk):

    def __init__(self, **kwargs):
       
        tk.Tk.__init__(self, )
        self.title('Anzahl Menues')
        self.geometry('300x130')    
   
        menu = tk.Menu(self, **kwargs)
        
        filemenu = tk.Menu(menu, tearoff=0)
        
        filemenu.add_command(label='Command')
                
        filemenu.add_checkbutton(label='Checkbutton')
                
        filemenu.add_separator()
        
        filemenu.add_radiobutton(value='radiobutton', label='radiobutton')
        
        print(filemenu.index(tk.END))        
        menu.add_cascade(label='Datei', menu=filemenu)
 
        self.config(menu=menu)
        
        print('Anzahl Menupunkte = {}'.format(self.menu_count(filemenu)))
        
    def menu_count(self, menu):
        # Separator und Tearoff werden nicht mitgezählt!
        num_menu = 0    
        for index in range(menu.index('end') + 1):
            menu_type = menu.type(index)
            if menu_type == 'tearoff' or menu_type == 'separator': continue
            num_menu += 1
        return num_menu


if __name__ == '__main__':
    Application().mainloop()
Gruss wuf :wink:
Take it easy Mates!
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Hi wuf, diese index Methode ist eine völlig falsch benannte Methode. Ich hatte mir eigentlich gedacht, dass sie das mit dem tearoff berücksichtigen würde und dachte an diese Lösung:

Code: Alles auswählen

    def count_menu_items(self):
        last_index = self.index(tk.END)
        first_index = self.index(0)
        print('how many: {}'.format(last_index - first_index + 1))

Aber keine Spur davon. Diese Methode kann man also nur für einen Zweck gebrauchen, nämlich um den letzten Index herauszubekommen. Viewiele es sind, ergibt sich dann durch:

Code: Alles auswählen

# -*- coding: utf-8 -*-

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk

class Application(tk.Tk):

    def __init__(self,**kwargs):
        tk.Tk.__init__(self,**kwargs)
        # widget definitions ===================================
        self.menu = Menu_1(self,tearoff=0)
        #self.menu = Menu_1(self)
        self['menu'] = self.menu

class Menu_1(tk.Menu):

    def __init__(self,master,**kwargs):
        tk.Menu.__init__(self,master,**kwargs)
        # widget definitions ===================================
        self.add_command(label='command')
        self.add_checkbutton(label='checkbutton')
        self.add_radiobutton(value='radiobutton', label='radiobutton')
        self.count_menu_items()

    def count_menu_items(self):
        x = self.index(tk.END) - self['tearoff'] + 1
        print('how many: {}'.format(x))
 
if __name__ == '__main__':
    Application().mainloop()
Natürlich zähle ich auch Separatoren mit. Es ging hautsächlich darum, um den letzten Index herauszubekommen. Dadurch kann ich jetzt auch Menüs von tcl/tk nach tkinter konvertieren.

Bleibt nur noch das labelwidget auch zu implementieren. Das ist das Widget, das man statt des Textes bei einem LabelFrame angeben kann. Ob ich aber dafür im Internet ein tcl/tk Beispiel finde? Denn leider verstehe ich kaum etwas von tcl/tk. Konvertieren kann man auch, ohne tcl/tk zu verstehen.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Ok Alfons
Alfons hat geschrieben:Denn leider verstehe ich kaum etwas von tcl/tk
In der Höhle von tcl/tk brennt meine Stirnlampe auch nicht. Eventuell gib es aber noch andere tcl/tk-Höhlenforscher in diesem Forum.

Gruss wuf :wink:
Take it easy Mates!
BlackJack

Naja, sooo schwer ist Tcl nicht, die Sprache an sich ist sogar recht primitiv auf eine Lisp-ähnliche Art und Weise, und Tk ist ja nur eine Bibliothek.

Eine Schaltfläche als Labelwidget:
[codebox=tcl file=Unbenannt.txt]#!/usr/bin/env tclsh
package require Tk

pack [labelframe .frame -labelwidget [button .button -text Test]]
#
# Just to have some content to show.
#
pack [label .frame.label -text {Some text...}][/code]
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

BlackJack hat geschrieben:Naja, sooo schwer ist Tcl nicht, die Sprache an sich ist sogar recht primitiv auf eine Lisp-ähnliche Art und Weise, und Tk ist ja nur eine Bibliothek.

Eine Schaltfläche als Labelwidget:
[codebox=tcl file=Unbenannt.txt]#!/usr/bin/env tclsh
package require Tk

pack [labelframe .frame -labelwidget [button .button -text Test]]
#
# Just to have some content to show.
#
pack [label .frame.label -text {Some text...}][/code]
Hi Blackjack, ich bräuchte noch eine Info. Bei padx etwa für pack oder grid kann man auch ein tuple angeben. Könntest Du mir bitte ein Beispiel dafür geben, damit ich dann schauen kann, was tcl/tk daraus liefert. Dieser Fall fehlt nämlich noch bei meiner Parser Routine für pack_info oder grid_info von tcl/tk.
BlackJack

@Alfons Mittelmeyer: In Tcl ist das eine Liste, also Werte in ``{`` und ``}`` eingefasst und durch Leerzeichen getrennt.
Antworten