I would like to display
a window
with a single Frame
and a Label in the Frame which would stretch to the whole width of the window
The following code
import Tkinter as tk
root = tk.Tk()
root.geometry("100x100")
# first column of root will stretch
root.columnconfigure(0, weight=1)
# a frame in root
upper_frame = tk.Frame(root)
# first column of upper_frame will stretch
upper_frame.columnconfigure(0, weight=1)
upper_frame.grid(row=0, column=0)
# a label in upper_frame, which should stretch
mylabel = tk.Label(upper_frame)
mylabel.grid(row=0, column=0)
mylabel.configure(text="hello", background="blue")
root.mainloop()
displays
Why isn't the Label stretching to the whole width of the window but is just as wide as the text?
Specifying sticky option when you call grid (e = east, w = west). Otherwise the widget in the cell is center-aligned.
upper_frame.grid(row=0, column=0, sticky='ew')
..
mylabel.grid(row=0, column=0, sticky='ew')
Related
I am new to Tkinter, I am trying to create a full-screen scrollable frame using Tkinter and canvas. here is my code:
from tkinter import *
from tkinter import ttk
root = Tk()
root.title('Learn To Code at Codemy.com')
root.geometry("500x400")
def FrameWidth(event):
canvas_width = event.width
canvas_height = event.height
my_canvas.itemconfig(canvas_frame, width = canvas_width)
# my_canvas.itemconfig(canvas_frame, height = canvas_height)
# my_canvas.itemconfig(canvas_frame, width = canvas_width, height = canvas_height)
def OnFrameConfigure(event):
my_canvas.configure(scrollregion=my_canvas.bbox("all"))
# Create A Main Frame
main_frame = Frame(root)
main_frame.grid(row=0, column=0, sticky='news')
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
main_frame.grid_columnconfigure(0, weight=1)
main_frame.grid_rowconfigure(0, weight=1)
# Create A Canvas
my_canvas = Canvas(main_frame, bg='red')
my_canvas.grid(row=0, column=0, sticky='news')
my_canvas.grid_columnconfigure(0, weight=1)
my_canvas.grid_rowconfigure(0, weight=1)
# Create ANOTHER Frame INSIDE the Canvas
second_frame = Frame(my_canvas, bg='blue')
# Add that New frame To a Window In The Canvas
canvas_frame = my_canvas.create_window((0,0), window=second_frame, anchor="nw")
# Add A Scrollbar To The Canvas
my_scrollbar = ttk.Scrollbar(main_frame, orient=VERTICAL, command=my_canvas.yview)
my_scrollbar.grid(row=0, column=1, sticky='ns')
my_canvas.configure(yscrollcommand=my_scrollbar.set)
main_frame.grid_rowconfigure(0, weight=1)
main_frame.grid_columnconfigure(0, weight=5)
main_frame.grid_columnconfigure(1, weight=0)
# Configure The Canvas
my_canvas.bind('<Configure>', FrameWidth)
second_frame.bind('<Configure>', OnFrameConfigure)
for thing in range(5):
Button(second_frame, text=f'Button {thing} Yo!').grid(row=thing, column=0, pady=10, padx=10, sticky = 'news')
my_label = Label(second_frame, text="It's Friday Yo!").grid(row=3, column=1, sticky='news')
second_frame.grid_columnconfigure(0,weight=4)
second_frame.grid_columnconfigure(1,weight=1)
root.mainloop()
my problem is that the frame with a blue background does not expand to full size and fill the canvas window, here is a screenshot of my app, my question is how to expand the second frame to fill entire window:
enter image description here
I am trying to fit widgets (e.g. buttons, labels (included images) into a Frame. Whenever I do this, the frame size changes to fit in the widget. So the widget does not 'fit' into the frame, but rather just expands the frames size.
E.g. see image below:
I have 3 frames:
root = Tk()
root.title('Model Definition')
root.geometry('{}x{}'.format(800, 600))
frame_1 = Frame(root, bg='red', pady=3)
frame_2 = Frame(root, bg='green', padx=3, pady=3)
frame_3 = Frame(root, bg='black', pady=3)
frame_1.grid(row=0, sticky='nsew')
frame_2.grid(row=1, sticky='nsew')
frame_3.grid(row=2, sticky='nsew')
# All frames expand at the same rate!
root.grid_rowconfigure(index=0, weight=1)
root.grid_rowconfigure(index=1, weight=1)
root.grid_rowconfigure(index=2, weight=1)
root.grid_columnconfigure(index=0, weight=1)
root.mainloop()
Each row has the same height when resizing the root window. If I add an image label to frame_1, the height of the frame expands to fit it in and so then when I expand the root window it disproportionately expands the size of the frame. (see below image)
Is there a way for the label to conform to the size of the frame? (i.e. to have the image within the boundaries set out of the frame)
scrollbar in Top level window created for a canvas is not working and how do I get region of canvas. where canvas size varies with number of buttons in it
I have created frame in tk(root) and one widget in a frame creates Top level window , which has multiple Buttons in a Frame.Number of Button varies with list. That Frame(which has buttons in it) exists in a canvas. My problem is that after putting scroll widget canvas do not moves
from tkinter import *
root = Tk()
root.geometry("500x200")
my_app= Frame(root)
my_app.pack()
my_window = Toplevel(my_app, bg='brown')
my_window.geometry("500x200+300+500")
top_window = Frame(my_window, bd=2, relief=SUNKEN)
top_window.grid_columnconfigure(0, weight=1)
yscrollbar = Scrollbar(top_window)
yscrollbar.grid(row=0, column=1, sticky=N+S)
canvas = Canvas(top_window, bd=0, yscrollcommand=yscrollbar.set)
canvas.config(scrollregion=(0, 0, 500, 1000))
canvas.grid(row=0, column=0, sticky=N+S+E+W)
yscrollbar.config( command = canvas.yview)
top_window.pack()
my_f = Frame(canvas)
def ins_ind(m):
print(m)
results =
["one","two","three","four","five","six","seven","eight","nine","ten"]
ins_list=[]
for ind, result in enumerate(results):
ins=str(result)
ins_list.append(ind)
ins_list[ind] = Button(my_f, text = ins, font='Times 12 bold',
bg='sandy brown',anchor=E, fg="black", command = lambda m=ins:
ins_ind(m) )
ins_list[ind].pack()
my_f.pack()
root.mainloop()
Scroll bar do no moves
For the buttons to move when you scroll the canvas you must put the buttons on the canvas.
Your code puts the buttons on the frame my_f. To put the buttons on the canvas you should use: canvas.create_window(x, y, window=button).
Is there a way using Tkinter to have buttons so that they are always placed a certain number of pixels from the edge of the window, even when the window is resized? I've tried using anchors but that didn't seem to move the placement in the window that much.
You can anchor buttons or any other widget to the sides of a window by starting with a Frame, and configuring its rows and columns to have a weight of 1 in order for it to fill the parent window.
import Tkinter as tk
import ttk
root = tk.Tk()
frame = ttk.Frame(root)
frame.pack(fill=tk.BOTH, expand=True)
frame.columnconfigure(index=0, weight=1)
frame.columnconfigure(index=2, weight=1)
frame.rowconfigure(index=0, weight=1)
frame.rowconfigure(index=2, weight=1)
Then, for each button you want to use sticky to anchor it to the respective side, and use padx or pady to add some padding (in pixels) between the button and the window.
top_padding = 5
top = ttk.Button(frame, text="Top")
top.grid(row=0, column=1, sticky=tk.N, pady=(top_padding, 0))
left_padding = 5
left = ttk.Button(frame, text="Left")
left.grid(row=1, column=0, sticky=tk.W, padx=(left_padding, 0))
right_padding = 5
right = ttk.Button(frame, text="Right")
right.grid(row=1, column=2, sticky=tk.E, padx=(0, right_padding))
bottom_padding = 5
bottom = ttk.Button(frame, text="Bottom")
bottom.grid(row=2, column=1, sticky=tk.S, pady=(0, bottom_padding))
root.mainloop()
have you tried using the padx function?
it works like this:
button=Button(place,text="something something", padx=10)
it provides with extra horizontal padding between widgets, aditionally, you could use frames with padx and an anchor so the text is fixated to a position
I am attempting to fit two buttons on a grid within a frame, that takes up the entire row, no matter the size of the root frame. So essentially one button takes up half of the row, while the other takes the other half. Here's my code:
self.button_frame = tk.Frame(self)
self.button_frame.pack(fill=tk.X, side=tk.BOTTOM)
self.reset_button = tk.Button(self.button_frame, text='Reset')
self.run_button = tk.Button(self.button_frame, text='Run')
self.reset_button.grid(row=0, column=0)
self.run_button.grid(row=0, column=1)
Not really sure where to go from here. Any suggestions would be greatly appreciated. Thanks!
Use columnconfigure to set the weight of your columns. Then, when the window stretches, so will the columns. Give your buttons W and E sticky values, so that when the cells stretch, so do the buttons.
import Tkinter as tk
root = tk.Tk()
button_frame = tk.Frame(root)
button_frame.pack(fill=tk.X, side=tk.BOTTOM)
reset_button = tk.Button(button_frame, text='Reset')
run_button = tk.Button(button_frame, text='Run')
button_frame.columnconfigure(0, weight=1)
button_frame.columnconfigure(1, weight=1)
reset_button.grid(row=0, column=0, sticky=tk.W+tk.E)
run_button.grid(row=0, column=1, sticky=tk.W+tk.E)
root.mainloop()
Result: