Note
The example code is an abridged version but can run with a basic function. Please focus on class MainWindow(tk.Frame)
Questions
What kind of object can play the role of the parent or master for tkinter class initialization?
In my case, see the example code, why can not pass self as parent to ProjectInfo(...) or ConfirmItems(...) in class MainWindow(tk.Frame)? It would pop up an empty window if using self instead of self.parent.
Reference
This question originates from my comments on Best way to structure a tkinter application, which means it fails to pass self as parent.
I would like to issue a new question to follow that discussions.
import tkinter as tk
from tkinter import messagebox
from collections import OrderedDict
class ProjectInfo(tk.Frame):
    def __init__(self, parent, controller, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.parent = parent
        self.controller = controller
        self.widgets_init()
    def widgets_init(self):
        tk.Label(self,
                    text = "Rock Controller!",
                    width = 10,
                    anchor = "w",
                    justify = "left").grid(row = 0, column = 0)
        tk.Label(self,
                    text = "Input Name: ").grid(row = 1, column = 0)
        self.entry = tk.Entry(self)
        self.entry.grid(row = 1, column = 1)
class ConfirmItems(tk.Frame):
    def __init__(self, parent, frames, controller, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.parent = parent
        self.frames = frames
        self.controller = controller
        self.widgets_init()
    def update_entries(self):
        self.controller.project_info.name = self.controller.project_info.entry.get()
    def update_frames(self):
        self.message = 'Click Cancel go back to reset!\n'
        for key, values in self.frames.items():
            for v in values:
                x = getattr(key, v)
                self.message += v + ': ' + str(x) + '\n'
    def show_settings(self):
        answer = tk.messagebox.askokcancel("Check Settings", self.message)
        if answer in ["yes", 1]:
            self.quit()
    def combine_funcs(self, *funcs):
        def combined_func(*args, **kwargs):
            for f in funcs:
                f(*args, **kwargs)
        return combined_func
    def widgets_init(self):
        self.cancel = tk.Button(self,
                                text = "Cancel",
                                command = self.quit)
        self.cancel.grid(row = 0, column = 0)
        self.submit = tk.Button(self,
                                text = "Submit",
                                command = self.combine_funcs(
                                                            self.update_entries,
                                                            self.update_frames,
                                                            self.show_settings))
                                # command = lambda:[self.update_frames(), self.show_settings()]
        self.submit.grid(row = 0, column = 1)
class MainWindow(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.parent = parent
        self.controller = self
        self.project_info = ProjectInfo(self.parent, self.controller)
        self.project_info.grid(row = 0)
        self.widgets_init()
        self.confirm_items = ConfirmItems(self.parent, self.frames, self.controller)
        self.confirm_items.grid(row = 1)
    def widgets_init(self):
        self.dict_list = [(self.project_info, ('name',))]
        self.frames = OrderedDict(self.dict_list)
def main():
    root = tk.Tk()
    root.title("Welcome to Controller World!")
    root.geometry("300x300")
    gui = MainWindow(root)
    root.mainloop()
if __name__ == "__main__":
    main()
 
    