Seite 1 von 1

Checkbuttons im Submenü

Verfasst: Samstag 10. Juni 2017, 17:01
von Alfons Mittelmeyer
Ich habe in einem Submenü zwei Checkbuttons.
Wenn ich da auf eine Checkbutton drücke, geht aber das Menü wieder zu.
Wenn ich auch den zweiten Checkbutton ankreuzen will, muss ich das Submenü wieder aufmachen.
Ich hätte aber gerne, dass man auch den zweiten Checkbutton ankreuzen kann, ohne dass das Menü wieder zugeht.
Gibt es dafür eine Lösung?

Re: Checkbuttons im Submenü

Verfasst: Samstag 10. Juni 2017, 23:20
von Alfons Mittelmeyer
OK, wenn keiner eine Lösung weiß, muss ich eben eine basteln

Re: Checkbuttons im Submenü

Verfasst: Sonntag 11. Juni 2017, 08:34
von Alfons Mittelmeyer
Habe schon etwas herausgefunden.

Wenn das sub sub Menü in der Cascade zum ersten Mal aufgeht, bekommt man 3 <Configure> events. Später sind es dann 2. Damit weiß man, wo dieses Menü ist und wie breit und wie hoch es ist:

Code: Alles auswählen

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


event_count = 0

def onFormEvent( event ):
    dir_event = dir( event )
    global event_count
    print('EVENT COUNT = ' + str(event_count))
    event_count += 1          
    print('_____________________')
    for key in dir_event:
        if not key.startswith( '_' ):
            print('%s=%s' % ( key, getattr( event, key ) ))
    print('------------------------')

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.Menu = Menu_2(self,activeforeground='black', activebackground='#7bfeff', fg='black', bg='white', tearoff=0, relief='solid')
        self.dyntk_name = 'File'
        self.add_cascade(menu=self.Menu,underline=0, label='File')

class Menu_2(tk.Menu):

    def __init__(self,master,**kwargs):
        tk.Menu.__init__(self,master,**kwargs)
        self.config(activeforeground='black', activebackground='#7bfeff', fg='black', bg='white', tearoff=0, relief='solid')
        # widget definitions ===================================
        self.dyntk_name = 'command1'
        self.add_command(underline=0, label='command1')
        self.dyntk_name = 'command2'
        self.add_command(underline=0, label='command2')
        self.dyntk_name = 'command3'
        self.add_command(underline=0, label='command3')
        self.dyntk_name = 'command4'
        self.add_command(label='command4')
        self.dyntk_name = 'command5'
        self.add_command(label='command5')
        self.dyntk_name = 'separator'
        self.add_separator()
        self.dyntk_name = 'command6'
        self.add_command(label='command6')
        self.Menu = Menu_3(self,activeforeground='black', activebackground='#7bfeff', fg='black', bg='white', tearoff=0, relief='solid')
        print('Menu_3',str(self.Menu))
        print()
        self.dyntk_name = 'cascade'
        self.add_cascade(menu=self.Menu,underline=0, label='cascade')
        self.dyntk_name = 'separator_quit'
        self.add_separator()
        self.dyntk_name = 'command7'
        self.add_command(label='command7')

class Menu_3(tk.Menu):

    def __init__(self,master,**kwargs):
        tk.Menu.__init__(self,master,**kwargs)
        self.config(activeforeground='black', activebackground='#7bfeff', fg='black', bg='white', tearoff=0, relief='solid')
        # widget definitions ===================================
        self.dyntk_name = 'command1'
        self.add_command(underline=0, label='command1')
        self.dyntk_name = 'command2'
        self.add_command(underline=9, label='command2')
        self.dyntk_name = 'command3'
        self.add_command(underline=9, label='command3')
        self.dyntk_name = 'separator'
        self.add_separator()
        self.dyntk_name = 'command4'
        self.add_command(label='command4')

        self.bind( '<Configure>', onFormEvent )

if __name__ == '__main__':
    Application().mainloop()

Das ist dann das Menü, das wir brauchen

Verfasst: Sonntag 11. Juni 2017, 08:51
von Alfons Mittelmeyer
Das ist dann das Menü, das wir brauchen. Und dieses ist der erste Streich:

Code: Alles auswählen

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


event_count = 0

def onFormEvent( event ):
    dir_event = dir( event )
    global event_count
    print('EVENT COUNT = ' + str(event_count))
    event_count += 1          
    print('_____________________')
    for key in dir_event:
        if not key.startswith( '_' ):
            print('%s=%s' % ( key, getattr( event, key ) ))
    print('------------------------')

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.Menu = Menu_2(self,activeforeground='black', activebackground='#7bfeff', fg='black', bg='white', tearoff=0, relief='solid')
        self.dyntk_name = 'File'
        self.add_cascade(menu=self.Menu,underline=0, label='File')

class Menu_2(tk.Menu):

    def __init__(self,master,**kwargs):
        tk.Menu.__init__(self,master,**kwargs)
        self.config(activeforeground='black', activebackground='#7bfeff', fg='black', bg='white', tearoff=0, relief='solid')
        # widget definitions ===================================
        self.dyntk_name = 'command1'
        self.add_command(underline=0, label='command1')
        self.dyntk_name = 'command2'
        self.add_command(underline=0, label='command2')
        self.dyntk_name = 'command3'
        self.add_command(underline=0, label='command3')
        self.dyntk_name = 'command4'
        self.add_command(label='command4')
        self.dyntk_name = 'command5'
        self.add_command(label='command5')
        self.dyntk_name = 'separator'
        self.add_separator()
        self.dyntk_name = 'command6'
        self.add_command(label='command6')
        self.Menu = Menu_3(self,activeforeground='black', activebackground='#7bfeff', fg='black', bg='white', tearoff=0, relief='solid')
        print('Menu_3',str(self.Menu))
        print()
        self.dyntk_name = 'cascade'
        self.add_cascade(menu=self.Menu,underline=0, label='cascade')
        self.dyntk_name = 'separator_quit'
        self.add_separator()
        self.dyntk_name = 'command7'
        self.add_command(label='command7')

class Menu_3(tk.Menu):

    def __init__(self,master,**kwargs):
        tk.Menu.__init__(self,master,**kwargs)
        self.config(tearoff=0, relief='flat', bd = 0, activeborderwidth = 0)
        self.bind( '<Configure>', onFormEvent )

if __name__ == '__main__':
    Application().mainloop()

Und das ist, was wir dazu brauchen

Verfasst: Sonntag 11. Juni 2017, 13:33
von Alfons Mittelmeyer

Code: Alles auswählen

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

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


class menu_toplevel(tk.Toplevel):

    def __init__(self,master,**kwargs):
        tk.Toplevel.__init__(self,master,**kwargs)
        self.overrideredirect(True)
        self.lift()
        self.config(bd=1, relief='solid', bg='white')
        # widget definitions ===================================
        self.checkbutton1 = tk.Checkbutton(self,text='checkbutton1', activeforeground='black', bg='white', bd='0', font='TkMenuFont', anchor='w', activebackground='#7bfeff', fg='black', highlightthickness='0')
        self.checkbutton2 = tk.Checkbutton(self,text='checkbutton2', activeforeground='black', bg='white', highlightcolor='black', bd='0', font='TkMenuFont', anchor='w', activebackground='#7bfeff', highlightbackground='white', fg='black', highlightthickness='0')
        self.command1 = tk.Button(self,pady='1', bd='0', font='TkMenuFont', relief='flat', anchor='w', padx='1m', activebackground='#7bfeff', activeforeground='black', fg='black', highlightthickness='0', bg='white', text='command1')
        self.command2 = tk.Button(self,pady='1', bd='0', font='TkMenuFont', relief='flat', anchor='w', padx='1m', activebackground='#7bfeff', activeforeground='black', fg='black', highlightthickness='0', bg='white', text='command2')
        self.command3 = tk.Button(self,pady='1', bd='0', font='TkMenuFont', relief='flat', anchor='w', padx='1m', activebackground='#7bfeff', activeforeground='black', fg='black', highlightthickness='0', bg='white', text='command3')
        self.help = tk.Button(self,pady='1', bd='0', font='TkMenuFont', relief='flat', anchor='w', padx='1m', activebackground='#7bfeff', activeforeground='black', fg='black', highlightthickness='0', bg='white', text='Help')
        self.separator1 = tk.Frame(self,bg='black', height=1)
        self.separator2 = tk.Frame(self,bg='black', height=1)
        self.checkbutton1.pack(padx=2, pady=2, anchor='w', fill='x')
        self.checkbutton2.pack(padx=2, pady=1, anchor='w')
        self.separator1.pack(pady=1, fill='x')
        self.command1.pack(padx=2, pady=1, anchor='w', fill='x')
        self.command2.pack(padx=2, pady=1, anchor='w', fill='x')
        self.command3.pack(padx=2, pady=1, anchor='w', fill='x')
        self.separator2.pack(fill='x')
        self.help.pack(padx=2, pady=1, anchor='w', fill='x')

if __name__ == '__main__':
    menu_toplevel(tk.Tk()).mainloop()
Und dieses war der zweite Streich

Es haut leider nicht ganz hin

Verfasst: Montag 12. Juni 2017, 13:15
von Alfons Mittelmeyer
Soweit bin ich gekommen:

Code: Alles auswählen

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

class MenuToplevel(tk.Toplevel):

    def __init__(self,master,**kwargs):
        tk.Toplevel.__init__(self,master,**kwargs)
        self.withdraw()
        self.overrideredirect(True)
        self.lift()

        self.config(bd=1, relief='solid', bg='white')
        # widget definitions ===================================
        self.checkbutton1 = tk.Checkbutton(self, text='checkbutton1', activeforeground='black', bg='white', bd='0', font='TkMenuFont', anchor='w', activebackground='#7bfeff', fg='black', highlightthickness='0')
        self.checkbutton2 = tk.Checkbutton(self,text='checkbutton2', activeforeground='black', bg='white', highlightcolor='black', bd='0', font='TkMenuFont', anchor='w', activebackground='#7bfeff', highlightbackground='white', fg='black', highlightthickness='0')
        self.command1 = tk.Button(self,command = self.button_click,pady='1', bd='0', font='TkMenuFont', relief='flat', anchor='w', padx='1m', activebackground='#7bfeff', activeforeground='black', fg='black', highlightthickness='0', bg='white', text='command1')
        self.command2 = tk.Button(self,command = self.button_click,pady='1', bd='0', font='TkMenuFont', relief='flat', anchor='w', padx='1m', activebackground='#7bfeff', activeforeground='black', fg='black', highlightthickness='0', bg='white', text='command2')
        self.command3 = tk.Button(self,command = self.button_click,pady='1', bd='0', font='TkMenuFont', relief='flat', anchor='w', padx='1m', activebackground='#7bfeff', activeforeground='black', fg='black', highlightthickness='0', bg='white', text='command3')
        self.help = tk.Button(self,command = self.button_click,pady='1', bd='0', font='TkMenuFont', relief='flat', anchor='w', padx='1m', activebackground='#7bfeff', activeforeground='black', fg='black', highlightthickness='0', bg='white', text='Help')
        self.separator1 = tk.Frame(self,bg='black', height=1)
        self.separator2 = tk.Frame(self,bg='black', height=1)
        self.checkbutton1.pack(padx=2, pady=2, anchor='w', fill='x')
        self.checkbutton2.pack(padx=2, pady=1, anchor='w')
        self.separator1.pack(pady=1, fill='x')
        self.command1.pack(padx=2, pady=1, anchor='w', fill='x')
        self.command2.pack(padx=2, pady=1, anchor='w', fill='x')
        self.command3.pack(padx=2, pady=1, anchor='w', fill='x')
        self.separator2.pack(fill='x')
        self.help.pack(padx=2, pady=1, anchor='w', fill='x')
        
        self.may_destroy = True
        self.bind('<Enter>', self.clear_destroy)
        self.bind('<Leave>', self.set_destroy)


    def set_destroy(self,event):
        self.may_destroy = True

    def clear_destroy(self,event):
        self.may_destroy = False

    def button_click(self):
        tk.Toplevel.destroy(self)

    def destroy(self):
        if self.may_destroy:
            tk.Toplevel.destroy(self)


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.Menu = Menu_2(self,activeforeground='black', activebackground='#7bfeff', fg='black', bg='white', tearoff=0, relief='solid')
        self.dyntk_name = 'File'
        self.add_cascade(menu=self.Menu,underline=0, label='File')

class Menu_2(tk.Menu):

    def __init__(self,master,**kwargs):
        tk.Menu.__init__(self,master,**kwargs)
        self.config(activeforeground='black', activebackground='#7bfeff', fg='black', bg='white', tearoff=0, relief='solid')
        # widget definitions ===================================
        self.dyntk_name = 'command1'
        self.add_command(underline=0, label='command1')
        self.dyntk_name = 'command2'
        self.add_command(underline=0, label='command2')
        self.dyntk_name = 'command3'
        self.add_command(underline=0, label='command3')
        self.dyntk_name = 'command4'
        self.add_command(label='command4')
        self.dyntk_name = 'command5'
        self.add_command(label='command5')
        self.dyntk_name = 'separator'
        self.add_separator()
        self.dyntk_name = 'command6'
        self.add_command(label='command6')
        self.Menu = Menu_3(self,activeforeground='black', activebackground='#7bfeff', fg='black', bg='white', tearoff=0, relief='solid')
        self.dyntk_name = 'cascade'
        self.add_cascade(menu=self.Menu,underline=0, label='cascade')
        self.dyntk_name = 'separator_quit'
        self.add_separator()
        self.dyntk_name = 'command7'
        self.add_command(label='command7')

class Menu_3(tk.Menu):

    def __init__(self,master,**kwargs):
        tk.Menu.__init__(self,master,**kwargs)
        self.config(tearoff=0, relief='flat', bd = 0, activeborderwidth = 0)
        self.bind( '<Configure>', self.onFormEvent )
        self.bind( '<Unmap>', self.onUnmap)
        self.bind( '<Visibility>', self.onVisibility)
        self.x = 0
        self.y = 0

    def onFormEvent(self,event ):
        self.x = getattr( event, 'x')
        self.y = getattr( event, 'y')

    def onUnmap(self,event):
        self.menu_toplevel.destroy()

    def onVisibility(self,event):
        self.menu_toplevel = MenuToplevel(self)
        self.menu_toplevel.deiconify()
        self.menu_toplevel.geometry('+{}+{}'.format(self.x,self.y))


if __name__ == '__main__':
    Application().mainloop()
Aber das Problem ist: solange das Menü geöffnet ist, geht nichts Anderes. Und wie man das Menü schließt, weiß ich nicht. Außerdem wäre so etwas auch Menü unübliches Verhalten.

Man könnte es natürlich statt als sub sub Menü nur als sub Menü machen und die Cascade in einen Command umfunktionieren und diesesToplevel dann unter dem Command platzieren. Nur ich möchte nicht weiteren Platz in der Menüleiste verschwenden. Außerdem wo wäre die x-Koordinate des commands?

Und selber eine Art von ganzem Menü aus Buttons statt Commands und Cascaden zusammenzubauen, geht mir zu weit.