@Tommilein: Weitere Anmerkungen:
`ttk` wird importiert, aber nirgends verwendet.
Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Kommentare sollen dem Leser einen Mehrwert über den Code geben. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das steht da bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist.
Eine `__init__()` die nur die `__init__()` der Basisklasse aufruft kann man sich sparen, das passiert auch so. Damit wäre die `WindowCreator`-Klasse leer, würde sich also im Verhalten überhaupt gar nicht von einem `Tk`-Objekt unterscheiden. Man kann da also direkt das `Tk`-Objekt verwenden.
Beim `FrameCreator` ist der Argument- und Attributname `root` unnötig einschränkend, denn da kann ja jedes beliebige Container-Widget übergeben werden, und nicht nur das Hauptfenster. Es müsste also `master` heissen, wie bei allen anderen Widgets auch. Auch beim `LabelCreator` würde ich es `master` nennen, denn das ist nun mal der Argumentname bei allen Widgets für dieses Argument.
Man braucht das nicht an ein Attribut binden, denn das passiert bereits in der ziemlich weit oben stehenden Basisklasse `BaseWidget`. Dieses Attribut gibt es also bereits nachdem man die `__init__()` der jeweiligen Basisklasse aufgerufen hat.
Widgets layouten sich nicht selbst. Der `pack()`-Aufruf gehört also nicht in die `__init__()` des Widgets sondern ausserhalb, nachdem ein Exemplar davon erstellt wurde.
Wenn man das `master`-Attribut setzen und den `pack()`-Aufruf aus der `__init__()` von `FrameCreator` und `LabelCreator` nimmt, dann bleibt wie beim `WindowCreator` nur der Aufruf der `__init__()` von der Basisklasse übrig, also eine `__init__()` die keinen Sinn macht. Und damit kann man dann auch diese beiden Klassen einfach weg lassen und direkt `Frame` und `Label` an ihrer Stelle verwenden.
Dann stellt sich noch die Frage warum nach dem erstellen von Frame- und Label-Objekt jeweils die `config()`-Methode aufgerufen wird, denn das kann man ja bereits alles *beim* erstellen angeben.
Damit bleibt dann von dem Programm das hier übrig:
Code: Alles auswählen
#!/usr/bin/env python3
import tkinter as tk
def main():
root = tk.Tk()
frame = tk.Frame(root, width=200, height=150, background="red")
frame.pack()
label = tk.Label(frame, width=7, height=5, background="yellow")
label.pack()
root.mainloop()
if __name__ == "__main__":
main()