Seite 1 von 1

Menu, Auswahl wird schon bei Initialisierung ausgeführt

Verfasst: Donnerstag 18. Oktober 2018, 18:37
von pyzip
Hallo, arbeite an einem Eingabefenster, das ein Menu, ein Label und ein Text-Widget mit Scrollbars enthalten soll. Nachdem ich das Text-Widget mit viel Mühe hinbekommen habe, komme ich nun mit dem Menu nicht klar. Es ist aus einem Tutorial und führt zu meiner Überraschung "command=" sofort aus. Erst wenn alle Menupunkte durch sind, kommt mein eigentliches Fenster und die Menupunkte haben keine Funktion mehr. Was verstehe ich dabei nicht? Ich hoffe auf Hilfe (wie immer...)
Danke und hier ist mein Programm:

Code: Alles auswählen

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Oct 16 16:50:22 2018

@author: pyzip
"""

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import tkinter as tk
from tkinter import messagebox, simpledialog, filedialog
 
class Diagramm(tk.Frame):
   
    def __init__(self, master):
        super().__init__(master)
        self.master = master

        self.menu = tk.Menu(self.master)
        self.master.config(menu=self.menu)
        self.filemenu = tk.Menu(self.menu)
        self.menu.add_cascade(label="File", menu=self.filemenu)
        self.filemenu.add_command(label="New", command=self.ask_new_filename())
        self.filemenu.add_command(label="Open...", command=self.choose_file())
        self.filemenu.add_separator()
        self.filemenu.add_command(label="Exit", command=self.master.quit)
        
        self.helpmenu = tk.Menu(self.menu)
        self.menu.add_cascade(label="Help", menu=self.helpmenu)
        self.helpmenu.add_command(label="About...", command=self.about())

        self.frame_l = tk.Frame(self.master, bg="yellow")
        self.frame_l.pack(fill=tk.BOTH,expand=True,padx=2,pady=2)

        self.frame_e = tk.Frame(self.master, bg="green",padx=2,pady=2)
        self.frame_e.grid_rowconfigure(0, weight=1)
        self.frame_e.grid_columnconfigure(0, weight=1)
        
        self.xscrollbar = tk.Scrollbar(self.frame_e, orient=tk.HORIZONTAL)
        self.xscrollbar.grid(row=1, column=0, sticky=tk.EW)
        
        self.yscrollbar = tk.Scrollbar(self.frame_e)
        self.yscrollbar.grid(row=0, column=1, sticky=tk.NS)
        
        self.text = tk.Text(self.frame_e, wrap=tk.NONE, bd=0,
                    xscrollcommand=self.xscrollbar.set,
                    yscrollcommand=self.yscrollbar.set)
        
        self.text.grid(row=0, column=0, sticky=tk.NSEW)
        
        self.xscrollbar.config(command=self.text.xview)
        self.yscrollbar.config(command=self.text.yview)

        self.frame_e.pack(padx=50,pady=2)
           
        self.labelText = tk.StringVar()
        self.labelText.set("Direkteigabe")

        self.w = tk.Label(self.frame_l, bg="red", textvariable=self.labelText)
        self.w.pack()
        
        ausgabe = "Hier steht Text..."
        self.text.insert(tk.END, ausgabe)

        
    def choose_file(self):
        self.file = filedialog.askopenfilename(filetypes = 
                    (("Text files","*.txt"),("all files","*.*")))
        return self.file
    
    def schliessen(self, master):
        antwort = messagebox.askyesno(
            'Schließen?',
            'Soll das Programm geschlossen werden?'
            ' Ggf. nicht gespeicherte Daten können verloren gehen!'
        )
        if antwort:
            master.quit()
     
    
    def about(self):
        messagebox.showinfo('Über', 'blabla')
     
     
    def ask_new_filename(self):
        filename_name = simpledialog.askstring(
            'Filename', 'Name ?'
        )
        if filename_name:
            new_filename = filename_name
            print("new_filename = ", new_filename)
            self.labelText.set(new_filename + "   "  + "Editor")

def main():
    
    title = "Eingabe"
    root = tk.Tk()
    root.title(title)

    w=800
    h=500
    ws=root.winfo_screenwidth()
    hs=root.winfo_screenheight()
    x=(ws/2)-(w/2)
    y=(hs/2)-(h/2)
    root.geometry('%dx%d+%d+%d'%(w,h,x,y))   
    
    dia = Diagramm(root)
    dia.pack()
    
     
    root.mainloop()


if __name__ == '__main__':
    main()

Re: Menu, Auswahl wird schon bei Initialisierung ausgeführt

Verfasst: Donnerstag 18. Oktober 2018, 18:57
von __blackjack__
@pyzip: Dass das sofort ausgeführt wird, sollte Dich aber nicht überraschen, denn Du hast das ja genau so im Code verlangt. Aufrufe und Argumente, bzw. deren Auswertung funktionieren in Python immer gleich. Erst werden die Argumente ausgewertet und dann wird eine Funktion oder Methode mit den ausgewerteten Argumenten aufgerufen. Das es sich um Tkinter handelt und das Argument `command` heisst, ändert daran nichts. `command` erwartet eine Rückruffunktion oder -methode als Argument. Du übergibst aber nicht die Methoden sondern rufst sie auf und übergibst deren Rückgabewert. Der 'Exit'-Menüpunkt funktioniert ja wie er soll. Vergleich mal was Du da nicht machst, im Gegensatz zu denen die nicht so funktionieren wie Du erwartet hast.

Re: Menu, Auswahl wird schon bei Initialisierung ausgeführt

Verfasst: Donnerstag 18. Oktober 2018, 19:59
von pyzip
@__blackjack__: Danke für die rasche Antwort! Bin nicht sicher, dass ich das richtig verstanden habe. Habe jetzt versuchsweise die Funktionen fürs Menu vor die Menu-Def. in gleicher Ebene geschoben und jetzt geht es!
Also

Code: Alles auswählen

 
class Diagramm(tk.Frame):
   
    def __init__(self, master):
        super().__init__(master)
        self.master = master
        def hello():
            print("hello!")
        
        def choose_file():
            file = filedialog.askopenfilename(filetypes = 
                        (("Text files","*.txt"),("all files","*.*")))
            print(file)
            return file
        
        self.menu = tk.Menu(self.master)
        self.master.config(menu=self.menu)
        self.filemenu = tk.Menu(self.menu)
        self.menu.add_cascade(label="File", menu=self.filemenu)
        self.filemenu.add_command(label="New", command=hello)
        self.filemenu.add_command(label="Open...", command=choose_file)
       
Habe mich an den "Buttons", die ich bisher genutzt habe, orientiert und dort wird der doch z.b mit einem "command=self.save" initialisiert, wobei "safe" eine Funktion der Klasse ist. Dachte also, dass der "Command" bei Menus auch erst ausgeführt wird, wenn der Menu-Eintrag angeklickt wird.
Ich hoffe, ich habe mich verständlich ausgedrückt. Habe trotzdem das Gefühl, dass ich noch nicht genau verstanden habe, was ich da gemacht habe.
Gruß pyzip

Re: Menu, Auswahl wird schon bei Initialisierung ausgeführt

Verfasst: Donnerstag 18. Oktober 2018, 20:15
von Sirius3
Du hast nicht nur (unsinnigerweise) die Funktionen verschoben, sondern auch noch etwas anderes geändert. Was ist das?

Was bewirkt der Rückgabewert von `choose_file`?

Re: Menu, Auswahl wird schon bei Initialisierung ausgeführt

Verfasst: Freitag 19. Oktober 2018, 01:53
von pyzip
Sorry, hat etwas gedauert...habe übersehen, dass "self.choose_file()" keine Methode ist. Es muß heissen "self.choose_file". Dann ist die Verschiebung natürlich überflüssig! Und der Rückgabewert von `choose_file` scheint mir auch sinnlos, da der Filename ja eh schon zugewiesen ist.
Also vielen Dank erst einmal und "gut's Nächtle", pyzip