Related
I want to create a GUI with two frames, one of which must be scrollable. I tried to create a scrollbar using canvas, but following the instructions from several tutorials I came to something strange:
I'm using the .grid method instead of the simple pack, because I want more control over the placement of elements (many in a row). I tried converting these tutorial methods from .pack to .grid, maybe that's why it doesn't work.
import customtkinter
import tkinter
class MyGui:
def __init__(self, app):
self.app = app
self.app.geometry("500x300")
self.app.grid_rowconfigure(0, weight=1)
self.app.grid_columnconfigure((0, 1), weight=1)
self.frame = customtkinter.CTkFrame(self.app)
self.frame.grid(
row=0, column=0, columnspan=3, padx=20, pady=(20, 5), sticky="NSEW"
)
self.canvas = customtkinter.CTkCanvas(self.frame)
self.canvas.grid(row=0, column=0, columnspan=3, sticky="NSEW")
self.scrollbar = customtkinter.CTkScrollbar(
master=self.frame, orientation="vertical", command=self.canvas.yview
)
self.scrollbar.grid(row=0, column=2, sticky="E")
self.canvas.configure(yscrollcommand=self.scrollbar.set)
self.frame_1 = customtkinter.CTkFrame(master=self.canvas)
self.frame_1.grid(
row=0, column=0, columnspan=3, padx=20, pady=(20, 5), sticky="NSEW"
)
self.canvas.create_window((0, 0), window=self.frame_1, anchor="nw")
self.frame_2 = customtkinter.CTkFrame(master=self.app)
self.frame_2.grid(
row=1, column=0, columnspan=3, padx=20, pady=(5, 20), sticky="NSEW"
)
for x in range(100):
customtkinter.CTkButton(self.frame_1, text=f"Button {x}").grid(
row=x, column=0
)
customtkinter.CTkEntry(
master=self.frame_1, placeholder_text=f"Entry {x}"
).grid(row=x, column=1)
customtkinter.CTkEntry(
master=self.frame_1, placeholder_text=f"Entry {x}"
).grid(row=x, column=2)
customtkinter.CTkButton(self.frame_2, text="Lonely button").pack(padx=5, pady=5)
app = customtkinter.CTk()
running = MyGui(app)
app.mainloop()
Also note that beside 'crashed' windows, scrollbar does not change position while scrolling because it takes up all his space and frames does not seem to expanding to fill the window.
I am creating a GUI in python using Tkinter and classes and having trouble resizing specific rows in the grid packager.
The code I have attached works but I would like to control the row widths so that the top 2 frames are static in size and the bottom resizes with the window. I have tried many things whilst referencing different solutions but nothing works.
# !/usr/bin/python3
# Use Tkinter for python 2, tkinter for python 3
import tkinter as tk
# Main Window
class WinMain(tk.Frame):
def __init__(self, master):
# parameters that you want to send through the Frame class.
tk.Frame.__init__(self, master)
# reference to the master widget, which is the tk window
self.master = master
# with that, we want to then run init_window, which doesn't yet exist
self.init_window()
def init_window(self):
# changing the title of our master widget
self.master.title("GUI Tester")
# Create menu for window
self.createMenu()
# Create Gui for window
self.createGui()
# Update Gui every second after 1 second
self.after(1000, self.upDateGui)
def createMenu(self):
# Initialise drop-down menu
menu = tk.Menu(self.master)
self.master.config(menu=menu)
# Add drop-down menu for Options
options = tk.Menu(menu, tearoff=False)
menu.add_cascade(label="Options", menu=options)
options.add_command(label="Open...", command=self.menuOptionsOpen)
options.add_separator()
options.add_command(label="Close", command=self.menuOptionsClose)
# Add drop-down menu for Help
help = tk.Menu(menu, tearoff=False)
menu.add_cascade(label="Help", menu=help)
help.add_command(label="About...", command=self.menuHelpAbout)
def createGui(self):
# Define GUI using Grid to place widgets
# Size window to its minimum set to 2/3 of the screen resolution
top = self.winfo_toplevel()
screen_width = top.winfo_screenwidth()
screen_height = top.winfo_screenheight()
screen_resolution = str(int(screen_width * 2 / 3)) + 'x' + str(int(screen_height * 2 / 3))
top.geometry(screen_resolution)
top.minsize(int(screen_width * 1 / 3), int(screen_height * 1 / 3))
# ------------------------------------------------
# create all frames
# ------------------------------------------------
self.c = self.master
self.c.frameTop = tk.LabelFrame(self.c, text="Top", width=5, height=5, padx=5, pady=5)
self.c.frameMiddle = tk.LabelFrame(self.c, text="Middle", width=5, height=5, padx=5, pady=5)
self.c.frameBottom = tk.LabelFrame(self.c, text="Bottom", width=5, height=5, padx=5, pady=5)
self.c.frameRight = tk.Frame(self.c, borderwidth=5, relief=tk.GROOVE)
# ------------------------------------------------
# Create widgets for frameTop
# ------------------------------------------------
# Text Box
self.c.frameTop.textBox = tk.Text(self.c.frameTop, borderwidth=3, relief=tk.SUNKEN)
self.c.frameTop.textBox.config(font=("consolas", 12), undo=True, wrap='none')
# Text Box Scroll Bars
self.c.frameTop.textBoxYScroll = tk.Scrollbar(self.c.frameTop, orient=tk.VERTICAL,
command=self.c.frameTop.textBox.yview)
self.c.frameTop.textBox['yscrollcommand'] = self.c.frameTop.textBoxYScroll.set
self.c.frameTop.textBoxXScroll = tk.Scrollbar(self.c.frameTop, orient=tk.HORIZONTAL,
command=self.c.frameTop.textBox.xview)
self.c.frameTop.textBox['xscrollcommand'] = self.c.frameTop.textBoxXScroll.set
# ------------------------------------------------
# Create widgets for frameMiddle
# ------------------------------------------------
# Text Box
self.c.frameMiddle.textBox = tk.Text(self.c.frameMiddle, borderwidth=3, relief=tk.SUNKEN)
self.c.frameMiddle.textBox.config(font=("consolas", 12), undo=True, wrap='none')
# Text Box Scroll Bars
self.c.frameMiddle.textBoxYScroll = tk.Scrollbar(self.c.frameMiddle, orient=tk.VERTICAL,
command=self.c.frameMiddle.textBox.yview)
self.c.frameMiddle.textBox['yscrollcommand'] = self.c.frameMiddle.textBoxYScroll.set
self.c.frameMiddle.textBoxXScroll = tk.Scrollbar(self.c.frameMiddle, orient=tk.HORIZONTAL,
command=self.c.frameMiddle.textBox.xview)
self.c.frameMiddle.textBox['xscrollcommand'] = self.c.frameMiddle.textBoxXScroll.set
# ------------------------------------------------
# Create widgets for frameBottom
# ------------------------------------------------
# Text Box
self.c.frameBottom.textBox = tk.Text(self.c.frameBottom, borderwidth=3, relief=tk.SUNKEN)
self.c.frameBottom.textBox.config(font=("consolas", 12), undo=True, wrap='none')
# Text Box Scroll Bars
self.c.frameBottom.textBoxYScroll = tk.Scrollbar(self.c.frameBottom, orient=tk.VERTICAL,
command=self.c.frameBottom.textBox.yview)
self.c.frameBottom.textBox['yscrollcommand'] = self.c.frameBottom.textBoxYScroll.set
self.c.frameBottom.textBoxXScroll = tk.Scrollbar(self.c.frameBottom, orient=tk.HORIZONTAL,
command=self.c.frameBottom.textBox.xview)
self.c.frameBottom.textBox['xscrollcommand'] = self.c.frameBottom.textBoxXScroll.set
# ------------------------------------------------
# Create widgets for frameRight
# ------------------------------------------------
self.c.frameRight.btnStatus = tk.Button(self.c.frameRight, text='Status Window', command=self.launchWinStatus)
self.c.frameRight.btnSpare1 = tk.Button(self.c.frameRight, text='Send Middle', command=self.btnSpare1)
self.c.frameRight.btnSpare2 = tk.Button(self.c.frameRight, text='Spare 2', command=self.btnSpare2)
# ------------------------------------------------
# ------------------------------------------------
# Layout widgets in frameTop
# ------------------------------------------------
self.c.frameTop.grid_columnconfigure(0, weight=1)
self.c.frameTop.grid_columnconfigure(1, weight=0)
self.c.frameTop.grid_rowconfigure(0, weight=1)
self.c.frameTop.grid_rowconfigure(1, weight=0)
self.c.frameTop.textBox.grid(row=0, column=0, sticky="nsew")
self.c.frameTop.textBoxYScroll.grid(row=0, column=1, sticky="nsew")
self.c.frameTop.textBoxXScroll.grid(row=1, column=0, sticky="nsew")
# ------------------------------------------------
# Layout widgets in frameMiddle
# ------------------------------------------------
self.c.frameMiddle.grid_columnconfigure(0, weight=1)
self.c.frameMiddle.grid_columnconfigure(1, weight=0)
self.c.frameMiddle.grid_rowconfigure(0, weight=1)
self.c.frameMiddle.grid_rowconfigure(1, weight=0)
self.c.frameMiddle.textBox.grid(row=0, column=0, sticky="nsew")
self.c.frameMiddle.textBoxYScroll.grid(row=0, column=1, sticky="nsew")
self.c.frameMiddle.textBoxXScroll.grid(row=1, column=0, sticky="nsew")
# ------------------------------------------------
# Layout widgets in frameBottom
# ------------------------------------------------
self.c.frameBottom.grid_columnconfigure(0, weight=1)
self.c.frameBottom.grid_columnconfigure(1, weight=0)
self.c.frameBottom.grid_rowconfigure(0, weight=1)
self.c.frameBottom.grid_rowconfigure(1, weight=0)
self.c.frameBottom.textBox.grid(row=0, column=0, sticky="nsew")
self.c.frameBottom.textBoxYScroll.grid(row=0, column=1, sticky="nsew")
self.c.frameBottom.textBoxXScroll.grid(row=1, column=0, sticky="nsew")
# ------------------------------------------------
# Layout widgets in frameRight
# ------------------------------------------------
self.c.frameRight.grid_columnconfigure(0, weight=0)
self.c.frameRight.grid_rowconfigure(0, weight=0)
self.c.frameRight.btnStatus.grid(row=0, column=0, sticky="nsew")
self.c.frameRight.btnSpare1.grid(row=2, column=0, sticky="nsew")
self.c.frameRight.btnSpare2.grid(row=3, column=0, sticky="nsew")
# ------------------------------------------------
# Layout frames in top container
# ------------------------------------------------
numOfCols = 2
numOfRows = 6
self.c.grid_columnconfigure(0, weight=1, pad=3)
self.c.grid_columnconfigure(1, weight=0, pad=3)
self.c.grid_rowconfigure(0, weight=1, pad=3)
self.c.grid_rowconfigure(1, weight=1, pad=3)
self.c.grid_rowconfigure(2, weight=1, pad=3)
self.c.grid_rowconfigure(3, weight=1, pad=3)
self.c.grid_rowconfigure(4, weight=1, pad=3)
self.c.grid_rowconfigure(5, weight=1, pad=3)
frameTopRowCol = [0, 0]
frameTopSpan = [2, 1]
frameMiddleRowCol = [frameTopRowCol[0] + frameTopSpan[0],
frameTopRowCol[1]]
frameMiddleSpanRC = [2, 1]
frameBottomRowCol = [frameMiddleRowCol[0] + frameMiddleSpanRC[0],
frameMiddleRowCol[1]]
frameBottomSpanRC = [2, 1]
frameRightRowCol = [frameTopRowCol[0],
frameTopRowCol[1] + frameTopSpan[1]]
frameRightSpanRC = [numOfRows, 1]
self.c.frameTop.grid(row=frameTopRowCol[0], column=frameTopRowCol[1],
rowspan=frameTopSpan[0], columnspan=frameTopSpan[1], sticky="nsew")
self.c.frameMiddle.grid(row=frameMiddleRowCol[0], column=frameMiddleRowCol[1],
rowspan=frameMiddleSpanRC[0], columnspan=frameMiddleSpanRC[1], sticky="nsew")
self.c.frameBottom.grid(row=frameBottomRowCol[0], column=frameBottomRowCol[1],
rowspan=frameBottomSpanRC[0], columnspan=frameBottomSpanRC[1], sticky="nsew")
self.c.frameRight.grid(row=frameRightRowCol[0], column=frameRightRowCol[1],
rowspan=frameRightSpanRC[0], columnspan=frameRightSpanRC[1], sticky="nsew")
# ------------------------------------------------
# Layout top container in window
# ------------------------------------------------
self.grid_columnconfigure(0, weight=1, pad=3)
self.grid_rowconfigure(1, weight=1, pad=3)
# ------------------------------------------------
# Layout window
# ------------------------------------------------
top.grid_columnconfigure(0, weight=1, pad=3)
top.grid_rowconfigure(1, weight=1, pad=3)
def menuOptionsOpen(self):
print("menuOptionsOpen")
def menuOptionsClose(self):
print("menuOptionsClose")
def menuHelpAbout(self):
print("menuHelpAbout")
def launchWinStatus(self):
print ("launchWinStatus")
def btnSpare1(self):
print("btnSpare1")
def btnSpare2(self):
print("btnSpare2")
def upDateGui(self):
print("upDateGui")
# Perform update every x milliseconds
self.after(1000, self.upDateGui)
# Main
def main():
root = tk.Tk()
app = WinMain(root)
root.mainloop()
# Launch Main
if __name__ == '__main__':
main()
I have a section at line 174 where I can change rowconfigure weights and this has peculiar effects that I can't explain. It should be able to fix the height of some rows while other rows are allowed to grow/shrink with the window down to a minimum size.
There are a few things:
There is a lot of code not relevant to the problem.
You have constructed a confusing widget hierarchy. The class WinMain()
is instantiated with root as master. While WinMain() inherits Frame(),
you never put any widgets inside self. Then you create the name top = self.winfo_toplevel() which is the running Tk() instance = root = master = self.master = self.c.
Your use of notation is confusing;
self.c.frameTop.textBox = tk.Text(self.c.frameTop, ...
Why save reference to the Text widget in the textBox attribute of frameTop?
Finally you configure grid in self (Frame which does not contain anything)
and root.
I think much of your problems are because you have confused the names of things. I'm providing an example below with only the necessary code to get the correct behaviour. My use of bg colors is to ease identification of the different widgets.
import tkinter as tk
# Main Window
class WinMain(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.master = master
self.master.config(bg='tan')
master.geometry('600x400+800+50')
self.pack(padx=10, pady=10, expand=True, fill='both')
self.columnconfigure(0, weight=1)
self.rowconfigure(2, weight=1) # Expand cols 0 & 2 with resize
# Top
frameTop = tk.LabelFrame(self, text="Top", bg='peru')
frameTop.grid(row=0, column=0, sticky='nsew')
frameTop.columnconfigure(0, weight=1) # Expand frame with resize
frameTop.rowconfigure(0, weight=1)
Top_Box = tk.Text(frameTop, borderwidth=3, relief=tk.SUNKEN, width=20, height=2)
Top_Box.grid(row=0, column=0, sticky="nsew", padx=10, pady=10)
# Middle
frameMiddle = tk.LabelFrame(self, text="Middle", padx=5, pady=5, bg='tomato')
frameMiddle.grid(row=1, column=0, sticky='nsew')
frameMiddle.columnconfigure(0, weight=1) # Expand frame with resize
frameMiddle.rowconfigure(0, weight=1)
Middle_Box = tk.Text(frameMiddle, borderwidth=3, relief=tk.SUNKEN, width=20, height=2)
Middle_Box.grid(row=0, column=0, sticky="nsew", padx=10, pady=10)
# Bottom
frameBottom = tk.LabelFrame(self, text="Bottom", padx=5, pady=5, bg='khaki')
frameBottom.grid(row=2, column=0, sticky='nsew')
frameBottom.columnconfigure(0, weight=1) # Expand frame with resize
frameBottom.rowconfigure(0, weight=1)
Bottom_Box = tk.Text(frameBottom, borderwidth=3, relief=tk.SUNKEN, width=20, height=2)
Bottom_Box.grid(row=0, column=0, sticky="nsew", padx=10, pady=10)
# Right
frameRight = tk.Frame(self, borderwidth=5, relief=tk.GROOVE, bg='thistle')
frameRight.grid(row=0, column=1, rowspan=3, sticky='nsew')
btnStatus = tk.Button(frameRight, text='Status Window',)
btnSpare1 = tk.Button(frameRight, text='Send Middle')
btnSpare2 = tk.Button(frameRight, text='Spare 2')
btnStatus.grid(row=0, column=0, sticky="ew")
btnSpare1.grid(row=1, column=0, sticky="ew")
btnSpare2.grid(row=2, column=0, sticky="ew")
if __name__ == '__main__':
root = tk.Tk()
app = WinMain(root)
root.mainloop()
Thanks for taking time to look at this. I've been struggling with this for almost a week and its driving me crazy.
I have a horizontal Paned Window which is supposed to stretch from the bottom of my toolbar to the bottom of my window, but it's sticking only to the bottom of the root window. Eventually I want to have a Treeview widget in the left pane and thumbnails in the right pane.
Can anyone help me to get the Paned Window to stick NSEW? Do I need to put it inside another frame?
I'm using Python 2.7 on Windows 7. (This isn't my whole program, just a sample to demonstrate the problem.)
#!/usr/bin/env python
# coding=utf-8
from Tkinter import *
from ttk import *
class MainWindow:
def null(self):
pass
def __init__(self):
self.root = Tk()
self.root.geometry("700x300")
self.root.resizable(width=TRUE, height=TRUE)
self.root.rowconfigure(0, weight=1)
self.root.columnconfigure(0, weight=1)
self.menubar = Menu(self.root)
File_menu = Menu(self.menubar, tearoff=0)
self.menubar.add_cascade(label="Pandoras Box", menu=File_menu)
File_menu.add_command(label="Black Hole", command=self.null)
self.root.config(menu=self.menubar)
self.toolbar = Frame(self.root, relief=RAISED)
self.toolbar.grid(row=0, column=0, sticky='NEW')
self.toolbar.grid_columnconfigure(0, weight=1)
self.toolbar.rowconfigure(0, weight=1)
dummy = Button(self.toolbar, text="Tool Button")
dummy.grid(row=0, column=0, sticky='EW')
Find = Label(self.toolbar, text="Search")
Search = Entry(self.toolbar)
Find.grid(row=0, column=5, sticky='E', padx=6)
Search.grid(row=0, column=6, sticky='E', padx=8)
self.info_column = Frame(self.root, relief=RAISED, width=100)
self.info_column.grid(row=0, column=5, rowspan=3, sticky='NSW')
self.info_column.grid_rowconfigure(0, weight=1)
self.info_column.grid_columnconfigure(0, weight=1)
self.rootpane = PanedWindow(self.root, orient=HORIZONTAL)
self.rootpane.grid(row=1, column=0, sticky='NS')
self.rootpane.grid_rowconfigure(0, weight=1)
self.rootpane.grid_columnconfigure(0, weight=1)
self.leftpane = Frame(self.rootpane, relief=RAISED)
self.leftpane.grid(row=0, column=0, sticky='NSEW')
self.rightpane = Frame(self.rootpane, relief=RAISED)
self.rightpane.grid(row=0, column=0, sticky='NSEW')
''' THESE BUTTONS ARE SUPPOSED TO BE INSIDE PANED WINDOW STUCK TO THE TOP!'''
but_left = Button(self.leftpane, text="SHOULD BE IN LEFT PANE UNDER TOOLBAR FRAME")
but_left.grid(row=0, column=0, sticky='NEW')
but_right = Button(self.rightpane, text="SHOULD BE IN RIGHT PANE UNDER TOOLBAR FRAME")
but_right.grid(row=0, column=0, sticky='NEW')
self.rootpane.add(self.leftpane)
self.rootpane.add(self.rightpane)
self.SbarMesg = StringVar()
self.label = Label(self.root, textvariable=self.SbarMesg, font=('arial', 8, 'normal'))
self.SbarMesg.set('Status Bar:')
self.label.grid(row=3, column=0, columnspan=6, sticky='SEW')
self.label.grid_rowconfigure(0, weight=1)
self.label.grid_columnconfigure(0, weight=1)
self.root.mainloop()
a = MainWindow()
Short answer: the space you see between the buttons and the toolbar frame is because you allow the row containing the toolbar to resize, instead of the row containing the PanedWindow... To get what you want, replace:
self.root.rowconfigure(0, weight=1)
with
self.root.rowconfigure(1, weight=1)
Other comments:
Try to avoid wildcard imports. In this case, it makes it difficult to differentiate between tk and ttk widgets
To allow resizing of widgets aligned using grid(), .rowconfigure(..., weight=x) must be called on the widget's parent not the widget itself.
background colors are very useful to debug alignment issues in tkinter.
Code:
import Tkinter as tk
import ttk
class MainWindow:
def __init__(self):
self.root = tk.Tk()
self.root.geometry("700x300")
self.root.resizable(width=tk.TRUE, height=tk.TRUE)
self.root.rowconfigure(1, weight=1)
self.root.columnconfigure(0, weight=1)
self.toolbar = tk.Frame(self.root, relief=tk.RAISED, bg="yellow")
self.toolbar.grid(row=0, column=0, sticky='NEW')
self.toolbar.columnconfigure(0, weight=1)
dummy = ttk.Button(self.toolbar, text="Tool Button")
dummy.grid(row=0, column=0, sticky='EW')
Find = tk.Label(self.toolbar, text="Search")
Search = ttk.Entry(self.toolbar)
Find.grid(row=0, column=5, sticky='E', padx=6)
Search.grid(row=0, column=6, sticky='E', padx=8)
self.info_column = tk.Frame(self.root, relief=tk.RAISED, width=100, bg="orange")
self.info_column.grid(row=0, column=5, rowspan=2, sticky='NSW')
self.rootpane = tk.PanedWindow(self.root, orient=tk.HORIZONTAL, bg="blue")
self.rootpane.grid(row=1, column=0, sticky='NSEW')
self.leftpane = tk.Frame(self.rootpane, bg="pink")
self.rootpane.add(self.leftpane)
self.rightpane = tk.Frame(self.rootpane, bg="red")
self.rootpane.add(self.rightpane)
''' THESE BUTTONS ARE SUPPOSED TO BE INSIDE PANED WINDOW STUCK TO THE TOP!'''
but_left = ttk.Button(self.leftpane, text="SHOULD BE IN LEFT PANE UNDER TOOLBAR FRAME")
but_left.grid(row=0, column=0, sticky='NEW')
but_right = ttk.Button(self.rightpane, text="SHOULD BE IN RIGHT PANE UNDER TOOLBAR FRAME")
but_right.grid(row=0, column=0, sticky='NEW')
self.label = tk.Label(self.root, text="Status:", anchor="w")
self.label.grid(row=3, column=0, columnspan=6, sticky='SEW')
self.root.mainloop()
a = MainWindow()
I can't assign a root based on an object created by a dictionary. I write down my code to make it simply. The problem comes up at the last row, where I want to set the button in the "Listado" frame. The button always appears at the bottom of the main App widget.
class App (tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.iconbitmap(self, default="codisalogo.ico")
tk.Tk.wm_title(self, "Codisa")
tk.Tk.configure(self, background="#ffffff")
tk.Tk.attributes(self, "-alpha", 1.0)
w, h = tk.Tk.winfo_screenwidth(self), tk.Tk.winfo_screenheight(self)
tk.Tk.geometry(self, "%dx%d+100+50"%(w/2, h/2))
tk.Tk.wm_minsize(self, width=w//2, height=h//2)
container = ttk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (PageOne, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column =0, sticky="nsew")
self.show_frame(PageOne)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.objects = {"listado": tk.Frame(self, background="#fffaf0", height=400, width=200, relief="raised").grid(row=1, column=2, columnspan=1, rowspan=2, padx=5),
"empresa": ttk.LabelFrame(self, text = "Empresa", height =200, width=200,relief= "sunken").grid(row=1, column=0, columnspan=1, padx=5),
"visitas": ttk.LabelFrame(self, text = "Visitas", height =200, width=200, relief= "groove").grid(row=1, column=1, columnspan=1, padx=5),
"historico": ttk.LabelFrame(self, text = "Histórico", height =200, width=410, relief= "raised").grid(row=2, column=0, columnspan=2, padx=5)}
self.objectslistado = {"empresa": ttk.Button(self.objects["listado"], text="Hola").pack()}
Thank you all"
The problem is that in your dictionary, you are mapping the strings "listado", "empresa", etc. to the result of the .grid() calls, which is None. This causes the Hola button to have a parent of None, which I believe defaults to the root window. You can see this if you add a print statement like so:
self.objects = {"listado": tk.Frame(self, background="#fffaf0", height=400, width=200, relief="raised").grid(row=1, column=2, columnspan=1, rowspan=2, padx=5),
"empresa": ttk.LabelFrame(self, text = "Empresa", height =200, width=200,relief= "sunken").grid(row=1, column=0, columnspan=1, padx=5),
"visitas": ttk.LabelFrame(self, text = "Visitas", height =200, width=200, relief= "groove").grid(row=1, column=1, columnspan=1, padx=5),
"historico": ttk.LabelFrame(self, text = "Histórico", height =200, width=410, relief= "raised").grid(row=2, column=0, columnspan=2, padx=5)}
print self.objects
self.objectslistado = {"empresa": ttk.Button(self.objects["listado"], text="Hola").pack()}
You should instead move the grid statements outside and do something along the lines of this (it might not be exactly what you want but this fixes the issue you're having):
self.objects = {"listado": tk.Frame(self, background="#fffaf0", height=400, width=200, relief="raised"),
"empresa": ttk.LabelFrame(self, text = "Empresa", height =200, width=200,relief= "sunken"),
"visitas": ttk.LabelFrame(self, text = "Visitas", height =200, width=200, relief= "groove"),
"historico": ttk.LabelFrame(self, text = "Historico", height =200, width=410, relief= "raised")}
self.objects["listado"].grid(row=1, column=2, columnspan=1, rowspan=2, padx=5)
self.objects["empresa"].grid(row=1, column=0, columnspan=1, padx=5)
self.objects["visitas"].grid(row=1, column=1, columnspan=1, padx=5)
self.objects["historico"].grid(row=2, column=0, columnspan=2, padx=5)
self.objectslistado = {"empresa": ttk.Button(self.objects["listado"], text="Hola").pack()}
When you enter a file name in the entry filed and click the "Open" button, the content will be displayed.
I want the Entry and Text widget to completely fill Frame3 (red) and continue to do so when the application window is resized. How do I achieve this?
This is my code:
from Tkinter import *
ALL = N+S+W+E
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master.rowconfigure(0, weight=1)
self.master.columnconfigure(0, weight=1)
self.grid(sticky=ALL)
def handler(event):
print("clicked at", event.x, event.y)
def show_entry_fields():
#print e1.get()
f=open(e1.get())
out_put=f.read()
l1=Label(f3, text=out_put,fg="purple").grid(row=5,column=2)
return out_put
def call_red():
out_put=show_entry_fields()
Label(f3, text=out_put,fg="red").grid(row=5,column=2)
def call_green():
out_put=show_entry_fields()
Label(f3, text=out_put,fg="green").grid(row=5,column=2)
def call_blue():
out_put=show_entry_fields()
Label(f3, text=out_put,fg="blue").grid(row=5,column=2)
def call_black():
out_put=show_entry_fields()
Label(f3, text=out_put,fg="black").grid(row=5,column=2)
for r in range(4):
self.rowconfigure(r, weight=1)
self.master.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
b1=Button(self, text="Red",command=call_red).grid(row=5, column=0, sticky=ALL)
self.columnconfigure(1, weight=1)
b2=Button(self, text="Blue",command=call_blue).grid(row=5, column=1, sticky=ALL)
self.columnconfigure(2, weight=1)
b3=Button(self, text="Green",command=call_green).grid(row=5, column=2, sticky=ALL)
self.columnconfigure(3, weight=1)
b4=Button(self, text="Black",command=call_black ).grid(row=5, column=3, sticky=ALL)
self.columnconfigure(4, weight=1)
b5=Button(self, text="Open",command=show_entry_fields).grid(row=5, column=4, sticky=ALL)
#------------------------------
f1 = Frame(self, bg="blue")
f1.grid(row=0, column=0, rowspan=2,columnspan=2, sticky=ALL)
f1.bind("<Button-1>", handler)
f1.focus()
f2 = Frame(self, bg="green")
f2.grid(row=2, column=0, rowspan=2,columnspan=2, sticky=ALL)
f2.bind("<Button-1>", handler)
f2.focus()
f3 = Frame(self, bg="red")
f3.grid(row=0, column=2, rowspan=4, columnspan=4, sticky=ALL)
l=Label(f3, text="Enter File Path:").grid(row=1)
e1 = Entry(f3)
e1.grid(row=1,column=2)
root = Tk()
app = Application(master=root)
app.mainloop()
You should assign a weight to the column and row in which you place the text:
f3.grid_columnconfigure(2, weight=1)
f3.grid_rowconfigure(5, weight=1)
This tells Tkinter that it should distribute any extra space to that row and column, which will make the cell grow upon resize.
You might want to add sticky=ALL to your e1 then too, so it resizes with the text below it.