Nachträgliche Button Funktion zuweisen, Name vom ParentFrame

Fragen zu Tkinter.
Antworten
eljobso
User
Beiträge: 1
Registriert: Montag 22. Oktober 2012, 08:29

Hallo zusammen,
Nachdem ich bei stackoverflow nur weniger Produktive Antworten bekommen habe, versuche ich es nun hier.
Ich habe ein Pyhton GUI Projekt nach dem MVC Modell aufgebaut. In meiner Klasse view befinden sich ausschließlich die GUI Elemente ohne jegliche Funktionen. In der Klasse controller werden den GUI Elementen die Funktionen zugewiesen (genauer gesagt im Konstruktor) und alle anderen benötigten Funktionen abgelegt.

Meine Probleme:
- im Konstruktor der Klasse controller soll dem BackButton nachträglich eine Funktion zugewiesen werden
- Übergabe des Namens des ParentFrames eines beliebigen Widgets (hier: Name des ParentFrames, in dem sich der BackButton befindet).

Danke für deine Hilfe.

Programmstruktur:

Code: Alles auswählen

from Tkinter import *
class View(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.title('Device Configurator')
        self.geometry('400x400')
        self.resizable(0,0)
        
        self.MainFrame = Frame(self, bd = '2', relief = RIDGE)
        self.MainFrame.pack(expand = True, fill="both", padx = 5, pady = 20)
       
        menubar = Menu(self)
        filemenu = Menu(menubar, tearoff=0)
        filemenu.add_command(label='Exit', command=self.quit)
        menubar.add_cascade(label='File', menu=filemenu)
        
        devicemenu = Menu(menubar, tearoff = 0)
        devicemenu.add_command(label = 'Edit Device List', command = self.deviceList)
        devicemenu.add_command(label = 'Screenshot', command = None)
        menubar.add_cascade(label = 'Device', menu = devicemenu)
        
        infomenu = Menu(menubar, tearoff = 0)
        infomenu.add_command(label='About', command = None)
        menubar.add_cascade(label='Info', menu = infomenu)
        
        self.config(menu = menubar)
    
    def mainMenu(self):
        labelMainMenu = Label(self.MainFrame, text = 'Main Menu', font = ("Helvetica", "16"))
        labelMainMenu.pack(padx = 5, pady = 5)
        configButton = Button(self.MainFrame, text = 'Device Configuration', font = ("Helvetica", "13"))
        configButton.pack(padx = 8, pady = 5)
        
        SCPIButton = Button(self.MainFrame, text = 'SCPI Command', font = ("Helvetica", "13"), command = self.SCPIMenu)
        SCPIButton.config(width = '18')
        SCPIButton.pack(padx = 8, pady = 5)
    
    def SCPIMenu(self):
        self.MainFrame.forget()
        self.SCPIFrame = Frame(self, bd = '2', relief = RIDGE)
        self.SCPIFrame.pack(expand = True, fill="both", padx = 5, pady = 20)
        
        self.IPLabel = Label(self.SCPIFrame, text = 'SCPI Command', font = ("Helvetica", "14"))
        self.IPLabel.pack(pady = 10)
        
        ##IP Frame
        self.IPFrame = Frame(self.SCPIFrame)
        self.IPFrame.pack(pady = 10)

        self.SCPIDeviceLabel = Label(self.IPFrame, text = 'IP Address:', font = ("Helvetica", "13"))
        self.SCPIDeviceLabel.config(width = '10')
        self.SCPIDeviceLabel.pack(side = 'left')
        self.SCPIDevice = Entry(self.IPFrame, font = ("Helvetica", "14"))
        self.SCPIDevice.pack(side = 'left', padx = 5, pady = 10)
        self.SCPIDevice.config(width = '15')
        self.SCPIPing = Button(self.IPFrame, text = 'Ping!', command = None, font = ("Helvetica", "10"))
        self.SCPIPing.pack(anchor = E, padx = 5, pady = 5, side = 'right')
        
        ##Ping Frame
        self.PingFrame = Frame(self.SCPIFrame)
        self.PingFrame.pack(padx = 30, pady = 1, anchor = E)
        self.PingBlankLabel = Label(self.PingFrame, text="")
        self.PingBlankLabel.pack(side = 'left', padx = 0, pady = 5)


        ##Command Frame
        self.CommandFrame = Frame(self.SCPIFrame)
        self.CommandFrame.pack(pady = 1)
        
        self.SCPICommandLabel = Label(self.CommandFrame, text = 'Command:', font = ("Helvetica", "13"))
        self.SCPICommandLabel.config(width = '8')
        self.SCPICommandLabel.pack(side = 'left', padx = 10, pady = 10)
        self.SCPICommand = Entry(self.CommandFrame, font = ("Helvetica", "14"))
        self.SCPICommand.pack(side = 'left', padx = 5, pady = 10)
        
        self.BackButton = Button(self.SCPIFrame, text = "Back", command = None, font = ("Helvetica", "13"))
        self.BackButton.place(x = 40, y = 330, anchor = CENTER)
    
        self.SendButton = Button(self.SCPIFrame, text = "Send", font = ("Helvetica", "13"))
        self.SendButton.place(x = 350, y = 330, anchor = CENTER)

       
    def deviceList(self):
        self.MainFrame.forget()
        self.deviceListFrame = Frame(self, bd = '2', relief = RIDGE)
        self.deviceListFrame.pack(expand = True, fill="both", padx = 5, pady = 20) 
        
        self.deviceListLabel = Label(self.deviceListFrame, text = 'Device List', font = ("Helvetica", "14"))
        self.deviceListLabel.pack(pady = 10)
        
        self.BackButton = Button(self.deviceListFrame, text = "Back", command = None, font = ("Helvetica", "13"))
        self.BackButton.place(x = 40, y = 330, anchor = CENTER)
    

Code: Alles auswählen

from view import *
import os
import sys

class Controller(object):
    def __init__(self):
        self.view = View()
        ---->Wie kann ich nachträglich die Funktion (also den command) des BackButtons zuweisen
        self.view.mainMenu()
        self.view.mainloop()
            
    def closeFrame(self):
        ---->Wie kann ich das aktuelle ParentFrame, in dem sich der BackButton befindet, zerstören (xxx.destroy())
        self.MainFrame.pack(expand = True, fill="both", padx = 5, pady = 20)
        
c = Controller()
BlackJack

@eljobso: So generische Namen wie `View` oder `Controller` für Klassen finde ich komisch. Das sind abstrakte Konzepte und daher eher ungewöhnlich für konkrete Klassen. Allenfalls als Postfix für den eigentlich Namen. Obwohl ich da wohl eher dem View ein `UI` als Präfix verpassen würde und dem Controller gar nichts. In Deinem Controller sind auch soweit ich das sehe ausschliesslich GUI-Sachen, die da IMHO nicht unbedingt hingehören.

Ich habe es mir nicht komplett durchgelesen, aber `Back`-Schaltfläche hört sich ein wenig nach einem Assistenten mit mehreren Seiten an. Das würde ich ich nicht in einer einzigen Klasse abfrühstücken sondern eine allgemeine Klasse schreiben die Platz für die Seiten bietet und Schaltflächen für das Blättern, und eine Liste von Seiten verwaltet die dann ausgewählt werden. Wenn die Python-Version halbwegs aktuell ist, eignet sich vielleicht ein `ttk.Notebook` mit versteckten Reitern als Basis.

Bezüglich der Namensschreibweise wirf mal einen Blick in PEP 8 -- Style Guide for Python Code.
Antworten