lilfarmerofa
lilfarmerofa

Reputation: 1

Label text isn't appearing in tkinter Frame

I've been researching this question, but none of the solutions I've found seem to work. I'm trying to get a Label (self.status_bar in the code below) to appear in my frame, but any edits (i.e. using update() method or resizing the frame/text widget/window) I've made have gotten me nowhere.

from tkinter import *
from tkinter import filedialog
from tkinter import font

#Build frame with features to put into parent window
class TextEditor:
    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master)
        
        #Create Scrollbar
        self.text_scroll = tk.Scrollbar(self.frame)
        self.text_scroll.pack(side=RIGHT, fill=Y)
        
        #Create text box
        self.text = tk.Text(self.frame, width=155, height=55, font=('Helvetica', 12), selectbackground="yellow",  
                            selectforeground = "black", undo=True, yscrollcommand=self.text_scroll.set)
        self.text.pack()
        
        #Configure scrollbar
        self.text_scroll.config(command=self.text.yview)
        
        #Create menu
        self.menu = tk.Menu(self.master)
        self.master.config(menu=self.menu)
        
        #Add file menu
        self.file_menu = tk.Menu(self.menu, tearoff=False)
        self.menu.add_cascade(label="File", menu=self.file_menu)
        self.file_menu.add_command(label="Open")
        self.file_menu.add_command(label="Save")
        self.file_menu.add_command(label="New")
        self.file_menu.add_separator()
        self.file_menu.add_command(label="Exit", command=self.master.destroy) 
        
        #Add edit menu
        self.edit_menu = tk.Menu(self.menu, tearoff=False)
        self.menu.add_cascade(label="Edit", menu=self.edit_menu)
        self.edit_menu.add_command(label="Cut")
        self.edit_menu.add_command(label="Copy")
        self.edit_menu.add_command(label="Undo")
        self.edit_menu.add_command(label="Redo")
        
        #Add status bar to bottom of app
        self.status_bar = tk.Label(self.frame, text="Ready", anchor=E)
        self.status_bar.pack(fill=X, side=BOTTOM, ipady=5)
        
        #Pack frame into window
        self.frame.pack()
        
#Instantiates the text editor app
def main():
    root = tk.Tk()
    app = TextEditor(root)
    root.geometry("1220x660")
    root.title("Text Editor")
    root.mainloop()
    
if __name__ == '__main__':
    main()

Upvotes: 0

Views: 773

Answers (2)

I suggest, with the more complicated layout you have, that you use the grid method instead of pack. Here is the code with the widgets gridded instead of packed:

import tkinter as tk
from tkinter import filedialog
from tkinter import font
from tkinter.constants import *

#Build frame with features to put into parent window
class TextEditor:
    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master)
        
        #Create Scrollbar
        self.text_scroll = tk.Scrollbar(self.frame)
        self.text_scroll.grid(row=0, column=1, sticky=E+NS) ### EDITED THIS LINE
        
        #Create text box
        self.text = tk.Text(self.frame, font=('Helvetica', 12), selectbackground="yellow",  ### EDITED THIS LINE
                            selectforeground = "black", undo=True, yscrollcommand=self.text_scroll.set)
        self.text.grid(row=0, column=0, sticky=NSEW) ### EDITED THIS LINE
        
        #Configure scrollbar
        self.text_scroll.config(command=self.text.yview)
        
        #Create menu
        self.menu = tk.Menu(self.master)
        self.master.config(menu=self.menu)
        
        #Add file menu
        self.file_menu = tk.Menu(self.menu, tearoff=False)
        self.menu.add_cascade(label="File", menu=self.file_menu)
        self.file_menu.add_command(label="Open")
        self.file_menu.add_command(label="Save")
        self.file_menu.add_command(label="New")
        self.file_menu.add_separator()
        self.file_menu.add_command(label="Exit", command=self.master.destroy) 
        
        #Add edit menu
        self.edit_menu = tk.Menu(self.menu, tearoff=False)
        self.menu.add_cascade(label="Edit", menu=self.edit_menu)
        self.edit_menu.add_command(label="Cut")
        self.edit_menu.add_command(label="Copy")
        self.edit_menu.add_command(label="Undo")
        self.edit_menu.add_command(label="Redo")
        
        #Add status bar to bottom of app
        self.status_bar = tk.Label(self.frame, text="Ready", anchor=E)
        self.status_bar.grid(row=1, column=0, sticky=S+EW) ### EDITED THIS LINE

        # Configure the rows and columns so that they expand properly ### ADDED THESE LINES
        self.frame.rowconfigure(0, weight=1) ### ADDED THESE LINES
        self.frame.columnconfigure(0, weight=1) ### ADDED THESE LINES
        
        #Pack frame into window
        self.frame.pack(expand=YES, fill=BOTH) ### EDITED THIS LINE
        
#Instantiates the text editor app
def main():
    root = tk.Tk()
    app = TextEditor(root)
    root.geometry("1220x660")
    root.title("Text Editor")
    root.mainloop()
    
if __name__ == '__main__':
    main()

Notice how I also changed the line where the frame is packed into the window. The only thing keeping the frame filling the window before was the size of the text widget.

With these changes, the widgets expand properly, so I also removed the width and height parameters from the creation of self.text.

Upvotes: 0

Bryan Oakley
Bryan Oakley

Reputation: 386342

You are forcing the window to a size that is too small to fit all of the widgets. When you do that while using pack, pack will start to shrink widgets in order to make them fit, starting with the last widget that was packed. In this case that's the status bar. So, pack starts removing pixels from self.status_bar until there's enough room for the other widgets. Eventually, it has to completely remove the status bar, and then start shrinking the text widget.

The first step is to create the status bar first, so that the text widget is higher in the stacking order (ie: pack will try to shrink it before shrinking other widgets).

The second thing you should do is use the appropriate options to get the TextEditor window to fill the frame, and get the frame to fill the window. For example:

self.text.pack(fill="both", expand=True)
self.frame.pack(fill="both", expand=True)

Upvotes: 1

Related Questions