简体   繁体   中英

GUI with tkinter does not show up

I am new to tkinter and have big problem with the GUI. My idea is to create a Menubar here and I have it already implemented (below you can find main.py and menu.py).

Unfortunately, when I run the program only a very, very small window appears. It's so small that I can't really see it. But I don't understand why. What did I do wrong here?

import tkinter as tk

from menu import Menu
#from toolbar import Toolbar
#from content import Content

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.parent = parent

        self.menu = Menu(self, background="yellow")

        # Toolbar and Content not implemented yet
        # self.toolbar = Toolbar(self, height=25, background="green")
        # self.content = Content(self, background="red")

        self.menu.pack()
        #self.toolbar.pack()
        #self.content.pack()

if __name__ == "__main__":
    root = tk.Tk()
    root.title("Editor")
    app = MainApplication(root)
    app.pack()
    root.config(menu=app.menu.menubar)
    root.mainloop()

That's the menu.py:

import tkinter as tk

class Menu(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.parent = parent
        self.menubar = tk.Menu(self)

        self.create_file_menu(self.menubar)
        self.create_edit_menu(self.menubar)
        self.create_view_menu(self.menubar)
        self.create_about_menu(self.menubar)

    def create_file_menu(self, parent):
        self.file_menu = tk.Menu(parent, tearoff=False)
        self.menubar.add_cascade(label="File", menu=self.file_menu)

        # Commands
        self.file_menu.add_command(label="New", accelerator="Ctrl+N", command=new_callback)
        self.file_menu.add_command(label="Open", accelerator="Ctrl+O", command=open_callback)
        self.file_menu.add_command(label="Save", accelerator="Ctrl+S", command=save_callback)
        self.file_menu.add_command(label="Save as", accelerator="Shift+Ctrl+S", command=saveas_callback)
        self.file_menu.add_separator()
        self.file_menu.add_command(label="Exit", accelerator="Alt+F4", command=exit_callback)

    def create_edit_menu(self, parent):
        self.edit_menu = tk.Menu(parent, tearoff=False)
        self.menubar.add_cascade(label="Edit", menu=self.edit_menu)

        # Commands
        self.edit_menu.add_command(label="Undo", accelerator="Ctrl+Z", command=undo_callback)
        self.edit_menu.add_command(label="Redo", accelerator="Ctrl+Y", command=redo_callback)
        self.edit_menu.add_separator()
        self.edit_menu.add_command(label="Cut", accelerator="Ctrl+X", command=cut_callback)
        self.edit_menu.add_command(label="Copy", accelerator="Ctrl+C", command=copy_callback)
        self.edit_menu.add_command(label="Paste", accelerator="Ctrl+V", command=paste_callback)
        self.edit_menu.add_separator()
        self.edit_menu.add_command(label="Find", accelerator="Ctrl+F", command=find_callback)
        self.edit_menu.add_separator()
        self.edit_menu.add_command(label="Select all", accelerator="Ctrl+A", command=selectall_callback)

    def create_view_menu(self, parent):
        self.view_menu = tk.Menu(parent, tearoff=False)
        self.menubar.add_cascade(label="View", menu=self.view_menu)

    def create_about_menu(self, parent):
        self.about_menu = tk.Menu(parent, tearoff=False)
        self.menubar.add_cascade(label="About", menu=self.about_menu)

        # Commands
        self.about_menu.add_command(label="About", command=about_callback)
        self.about_menu.add_command(label="Help", command=help_callback)

def new_callback():
    pass

def open_callback():
    pass

def save_callback():
    pass

def saveas_callback():
    pass

def exit_callback():
    pass

def undo_callback():
    pass

def redo_callback():
    pass

def cut_callback():
    pass

def copy_callback():
    pass

def paste_callback():
    pass

def find_callback():
    pass

def selectall_callback():
    pass

def about_callback():
    pass

def help_callback():
    pass

I am not knowledgeable with the use of super() . I have replaced it with tk.Frame and made a few other changes which is accompanied with explanation/comment. See the revised codes given below. For the revised menu.py, you have to append the relevant sections from where I left off for the code to work (save display space).

I was able to get a non-zero width Tk window when the script was executed. Hope this solution helps you answer your question.

Revised Main.py

import tkinter as tk

from menu import Menu

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        #super().__init__(parent, *args, **kwargs) #replaced with below sentence
        tk.Frame.__init__(self, parent, *args, **kwargs) #added
        self.parent = parent

        #self.menu = Menu(self, background="yellow") #replaced with below 3 sentences
        self.menu = Menu(self) #added: Instantiate the class Menu as self.menu
        self.menubar = self.menu.menubar #added: relate the local variable for menubar(i.e. self.menubar) with the menubar variable in the instance self.menu.
        self.menubar.configure(background = 'yellow') #added, configure the background

        # If you comment the above 3 sentences and uncomment the below,
        # you will get the same window
        """self.menubar = tk.Menu(self.parent, background="yellow")
        self.create_file_menu(self.menubar)
        self.create_edit_menu(self.menubar)
        self.create_view_menu(self.menubar)
        self.create_about_menu(self.menubar)

    def create_file_menu(self, parent):
        self.file_menu = tk.Menu(parent, tearoff=False)
        self.menubar.add_cascade(label="File", menu=self.file_menu)

    def create_edit_menu(self, parent):
        self.edit_menu = tk.Menu(parent, tearoff=False)
        #self.menubar.add_cascade(label="Edit", menu=self.edit_menu)

    def create_view_menu(self, parent):
        self.view_menu = tk.Menu(parent, tearoff=False)
        self.menubar.add_cascade(label="View", menu=self.view_menu)

    def create_about_menu(self, parent):
        self.about_menu = tk.Menu(parent, tearoff=False)
        self.menubar.add_cascade(label="About")"""

if __name__ == "__main__":
    root = tk.Tk()
    root.title("Editor")
    app = MainApplication(root)
    #app.pack() # this caused the zero width Window
    root.configure(menu=app.menu.menubar)
    root.mainloop()

Revised menu.py (Relevant part) :

import tkinter as tk

class Menu(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        #super().__init__(parent, *args, **kwargs) #replaced with below sentence
        tk.Frame.__init__(self, parent, *args, **kwargs) #added
        self.parent = parent
        self.menubar = tk.Menu(self)

As I said in comments, apparently one can't attach a tk.Menu to a tk.Frame and have it things work correctly—however a workaround using tk.Menubutton was suggested, so here's a modified version of your menu.py that demonstrates how to implement said method of overcoming that limitation.

Basically each top menu item is now a tk.Menubtton . The choices (picks) underneath each one are still separate tk.Menu s as before. I also used the grid layout manager to arrange them in a single row. You can probably do the same thing with pack , but as I mentioned, I'm not familiar with it. Besides, there's no harm in an independent tk.Frame using a different layout manager than its parent does.

No changes were made or required to your main.py file. I put all those dummy callback functions you added to menu.py into a separate callbacks.py file which is now import ed it near the beginning in the revised version of the file below.

Modified menu.py :

import tkinter as tk
from callbacks import *  # all the dummy callback functions...

class Menu(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

        self.create_file_menu()
        self.create_edit_menu()
        self.create_view_menu()
        self.create_about_menu()

    def create_file_menu(self):
        self.file_menu = tk.Menubutton(self, text='File')
        picks = tk.Menu(self.file_menu)
        self.file_menu.config(menu=picks)

        # Commands
        picks.add_command(label='New', accelerator='Ctrl+N', command=new_callback)
        picks.add_command(label='Open', accelerator='Ctrl+O', command=open_callback)
        picks.add_command(label='Save', accelerator='Ctrl+S', command=save_callback)
        picks.add_command(label='Save as', accelerator='Shift+Ctrl+S', command=saveas_callback)
        picks.add_separator()
        picks.add_command(label='Exit', accelerator='Alt+F4', command=exit_callback)

        self.file_menu.grid(row=0, column=0)

    def create_edit_menu(self):
        self.edit_menu = tk.Menubutton(self, text='Edit')
        picks = tk.Menu(self.edit_menu)
        self.edit_menu.config(menu=picks)

        # Commands
        picks.add_command(label='Undo', accelerator='Ctrl+Z', command=undo_callback)
        picks.add_command(label='Redo', accelerator='Ctrl+Y', command=redo_callback)
        picks.add_separator()
        picks.add_command(label='Cut', accelerator='Ctrl+X', command=cut_callback)
        picks.add_command(label='Copy', accelerator='Ctrl+C', command=copy_callback)
        picks.add_command(label='Paste', accelerator='Ctrl+V', command=paste_callback)
        picks.add_separator()
        picks.add_command(label='Find', accelerator='Ctrl+F', command=find_callback)
        picks.add_separator()
        picks.add_command(label='Select all', accelerator='Ctrl+A', command=selectall_callback)

        self.edit_menu.grid(row=0, column=1)


    def create_view_menu(self):
        self.view_menu = tk.Menubutton(self, text='View')
        picks = tk.Menu(self.view_menu)
        self.view_menu.config(menu=picks)

        # Commands
        submenu = tk.Menu(picks)
        picks.add_cascade(label='Views', menu=submenu)
        submenu.add_command(label='View 1', command=lambda: None)
        submenu.add_command(label='View 2', command=lambda: None)

        self.view_menu.grid(row=0, column=2)

    def create_about_menu(self):
        self.about_menu = tk.Menubutton(self, text='About')
        picks = tk.Menu(self.about_menu)
        self.about_menu.config(menu=picks)

        # Commands
        picks.add_command(label='About', command=about_callback)
        picks.add_command(label='Help', command=help_callback)

        self.about_menu.grid(row=0, column=3)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM