Menü-Aktualisierung und Bilder im Toplevel

Fragen zu Tkinter.
Antworten
yeti
User
Beiträge: 8
Registriert: Dienstag 3. November 2009, 23:35

Hallo zusammen,

ich habe eine Frage zum dynamischen Ändern eines Menüs: Durch postcommand ist ja möglich, die Einträge zu verändern. Allerdings würde ich gerne das Menü direkt nach dem Auswählen eines Menüpunktes ggf. anders darstellen (in einer anderen Sprache) Gibt es eine Möglichkeit, dies per event zu machen? Ich bin leider zu keiner Lösung gekommen und würde mich über Anregungen freuen. Der Code folgt weiter unten.

Gleichzeitig habe ich ein anderes Problem, das ebenfalls in dem Code unten geschieht: Ich öffne ein weiteres Fenster durch den Menüeintrag "Impressum". Dort kann ich Labels darstellen aber scheinbar keine Bilder. Kann mir jemand sagen, was ich dort übersehen habe?

Besten Dank schonmal und hier kommt der Code


Code: Alles auswählen

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

from Tkinter import *
import Image, ImageTk

languageMenu = { 'de':u'Sprache',
                 'el':u'EL_Lang',
                 'en':u'Language',
                 'fr':u'Langue',
                 'ro':u'Limba?',
                 'tr':u'TR_Lang'
               }

root = Tk()
root.geometry('800x600')


class MainDialog:

    def __init__(self, parent):

        self.myParent = parent
        self.myFrame = Frame(parent, bg='#002244')
        self.myFrame.grid()
        self.language = 'en'
        
    def updateLanguage(self, newLanguage):
            self.language = newLanguage


md = MainDialog(root)

multiling_menu = 'Language'

def updateMenu():

    global multiling_menu
    
    if md.language == 'de':
        multiling_menu = 'Sprache'
    elif md.language == 'en':
        multiling_menu = 'Language'
    elif md.language == 'el':
        multiling_menu = 'EL_Lang'
    elif md.language == 'fr':
        multiling_menu = 'Langue'
    elif md.language == 'ro':
        multiling_menu = 'RO_Lang'
    elif md.language == 'tr':
        multiling_menu = 'TR_Lang'
        
    menu.entryconfig(1, label=languageMenu[md.language])

    menu.update()
    

class InfoDialog():

        def __init__(self, parent):
            
            top = self.top = Toplevel(parent)

            lang_label=""
            if md.language == 'de':
                lang_label = 'Sprache'
            elif md.language == 'en':
                lang_label = 'Language'
            elif md.language == 'el':
                lang_label = 'EL_Lang'
            elif md.language == 'fr':
                lang_label = 'Langue'
            elif md.language == 'ro':
                lang_label = 'RO_Lang'
            elif md.language == 'tr':
                lang_label = 'TR_Lang'
            Label(top, text=lang_label).pack()

            info_img1  = Image.open('.\\media\\1_LAND.gif')
            info_pimg1 = ImageTk.PhotoImage(info_img1)
            Label(self.top, image=info_pimg1, bg='#002244').pack()
    

menu = Menu(root, postcommand=updateMenu)
root.config(menu=menu)
languagemenu = Menu(menu, tearoff=0)
menu.add_cascade(label=multiling_menu, menu=languagemenu)

languagemenu.add_command(label='Deutsch', command = lambda
                         arg1= 'de': md.updateLanguage(arg1))
languagemenu.add_command(label=u'EL', command = lambda
                         arg1= 'el': md.updateLanguage(arg1))
languagemenu.add_command(label='English', command = lambda
                         arg1= 'en': md.updateLanguage(arg1))
languagemenu.add_command(label=u'Fran\xe7ais', command = lambda
                         arg1= 'fr': md.updateLanguage(arg1))
languagemenu.add_command(label=u'Romana', command = lambda
                         arg1= 'ro': md.updateLanguage(arg1))
languagemenu.add_command(label=u'Türk\xe7e', command = lambda
                         arg1= 'tr': md.updateLanguage(arg1))

menu.add_command(label='Impressum', command= lambda
                         arg1= root: InfoDialog(arg1))

root.mainloop()
[/code]
heribert
User
Beiträge: 3
Registriert: Samstag 25. Juli 2009, 13:30
Wohnort: Gütersloh

Hallo yeti
wenn du im MainDialog in updateLanguage dein updateMenue aufrufst nachdem du die Sparche gesetzt hast, dann wird sofort umgeschaltet.
bei dem Dialog-Fenster solltest di 2 Dinge beachten:
1. Die Varibale in die du das Image lädst, muss beim Anzeige(repaint) des Fensters noch vorhanden sein. Da du im InfoDialog im __ini__ eine lokale Varibale verwendest, ist die nicht mehr vorhanden, und dein Bild wird nicht mehr angezeigt. 'Besser' so:

Code: Alles auswählen


info_pimg1 = None
class InfoDialog():

        def __init__(self, parent):
            global info_pimg1
2. So wie du InfoDialog angelegt hast, wird als NonModaler Dialog ausgeführt, das heist, das dein Hauptfenster weiter aktiv bleibt, du kannst mehrmals auf Impressum klicken wenn bereits ein Impressum Fenster geöffnet ist, und bekommst immer mehr Fenster angezeigt. Besser du erstellt eine Klassen die von tkSimpleDialog.Dialog abgeleitet ist. ich habe für mich folgende Klasse erstellt, die eine Infobox mit ttk-Buttons erstellt. (ttk = more Windows like Widgets)

Code: Alles auswählen

class Infobox(tkSimpleDialog.Dialog):
    """Informationsbox anzeigen"""

    def __init__(self, master, titel, Text='', Icon=None, FensterIcon=None):
        """Icon: Icon links neben dem Text
        FensterIcon: Icon für den Fensterrahmen"""
        self._DIALOGTITEL = titel
        self._TEXT = Text
        self._ICON = Icon
        self._FENSTERICON = FensterIcon
        tkSimpleDialog.Dialog.__init__(self, master, title=titel)

    def buttonbox(self):
        """Eigene Buttons erstellen"""
        box = ttk.Frame(self)
        w = ttk.Button(box, text="OK", command=self.ok, default=Tkinter.ACTIVE)
        w.pack(side=Tkinter.RIGHT, padx=5, pady=5)
        box.pack(side=Tkinter.TOP, fill=Tkinter.BOTH)

    def body(self, _):
        """Anzeige erstellen"""
        if self._FENSTERICON is not None:
            self.wm_iconbitmap(self._FENSTERICON)
        box = Tkinter.Frame(self, bg='white')
        if self._ICON is not None:
            self._bodyIcon = Tkinter.PhotoImage(data=self._ICON)
            Tkinter.Label(box, image=self._bodyIcon, anchor=Tkinter.N, bg='white').pack(side=Tkinter.LEFT, fill=Tkinter.BOTH, pady=20)
        text = Tkinter.Label(box, text=self._TEXT, justify=Tkinter.LEFT, bg='white')
        text.pack(side=Tkinter.LEFT, padx=20, pady=20)
        box.pack(side=Tkinter.TOP)
yeti
User
Beiträge: 8
Registriert: Dienstag 3. November 2009, 23:35

Herzlichen Dank für die Antworten, heribert!
Antworten