import tkinter
from tkinter import ttk
class GUI(tkinter.Tk):
def __init__(self):
tkinter.Tk.__init__(self)
self.geometry("500x500")
self.title("Red Frame Example")
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
red_frame_style = ttk.Style()
red_frame_style.configure("RedFrame.TFrame", background = "red")
red_frame = ttk.Frame(self, style="RedFrame.TFrame", width="250", height="250")
red_frame.grid_rowconfigure(0, weight=1)
red_frame.grid_columnconfigure(0, weight=1)
red_frame.grid(row=0, column=0, sticky="n")
button = tkinter.Button(red_frame, text='Stop', width=25, command=self.destroy)
button.grid(row = 1, column = 0)
gui = GUI()
gui.mainloop()
I am trying to get a 250 by 250 red frame to show up on my window in tkinter. Answers to this question suggested splitting a line like red_frame = tkinter.Frame(self, style="RedFrame.TFrame", width="250", height="250").grid(row=0, column=0, sticky="n") into 2 different lines, which is what I tried to do in my code below, but the red frame still did not appear. What am I doing wrong here, and how can I fix it?
Related
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
left_frame_1 = tk.Frame(root, background="#ff0000")
left_frame_1.grid(row=0, column=0)
left_frame_2 = tk.Frame(left_frame_1)
left_frame_2.grid(row=0, column=0)
left_label_1 = tk.Label(left_frame_2, text="HELLO")
left_label_2 = tk.Label(left_frame_2, text="WORLD")
left_label_3 = tk.Label(left_frame_2, text="=D")
left_label_1.grid(row=0, column=0)
left_label_2.grid(row=1, column=0)
left_label_3.grid(row=2, column=0)
right_frame1 = tk.Frame(root, background="#00ff00")
right_frame1.grid(row=0, column=1, sticky="nsew")
right_frame_2 = tk.Frame(right_frame1, background="#0000ff")
right_frame_2.grid(row=0, column=0)
right_label_1 = tk.Label(right_frame_2, text="CENTER ME!")
right_label_1.grid(row=0, column=0)
root.mainloop()
When my parent frame expands to all its free space, the child frame doesn't, instead it just stays on top.
I've been testing if .grid() has something to do with it, but haven't found anything.
Even if I add sticky="nsew" to both the frame and the label, there is still no change.
right_frame1 = tk.Frame(root, background="#00ff00")
right_frame1.grid(row=0, column=1, sticky="nsew")
right_frame_2 = tk.Frame(right_frame1, background="#0000ff")
right_frame_2.grid(row=0, column=0, sticky="nsew")
right_label_1 = tk.Label(right_frame_2, text="CENTER ME!")
right_label_1.grid(row=0, column=0, sticky="nsew")
My goal is for the parent frame (the one with the green color) to expand to all available space (which I've achieved), and for the child frame containing the label to expand.
right_frame_2 looks because it expands.
right_frame_1 is not visible because it is completely covered by right_frame_2.
I hope your help, thank you.
To get the result of the last image in the question, you need to:
change sticky options of .grid() for right_frame_2 and right_label_1
set weight options of .rowconfigure() and .columnconfigure() on root, right_frame1 and right_frame_2
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
left_frame_1 = tk.Frame(root, background="#ff0000")
left_frame_1.grid(row=0, column=0)
left_frame_2 = tk.Frame(left_frame_1)
left_frame_2.grid(row=0, column=0)
left_label_1 = tk.Label(left_frame_2, text="HELLO")
left_label_2 = tk.Label(left_frame_2, text="WORLD")
left_label_3 = tk.Label(left_frame_2, text="=D")
left_label_1.grid(row=0, column=0)
left_label_2.grid(row=1, column=0)
left_label_3.grid(row=2, column=0)
right_frame1 = tk.Frame(root, background="#00ff00")
right_frame1.grid(row=0, column=1, sticky="nsew")
right_frame_2 = tk.Frame(right_frame1, background="#0000ff")
right_frame_2.grid(row=0, column=0, sticky="nsew") # expand to fill available space
right_label_1 = tk.Label(right_frame_2, text="CENTER ME!")
right_label_1.grid(row=0, column=0, sticky="ew") # expand horizontally
root.rowconfigure(0, weight=1) # make left and right frame expand vertically
root.columnconfigure(1, weight=1) # make right frame expand horizontally
# allocate all space to right_frame_2
right_frame1.rowconfigure(0, weight=1)
right_frame1.columnconfigure(0, weight=1)
# allocate all space of right_frame_2 to right_label_1
right_frame_2.rowconfigure(0, weight=1)
right_frame_2.columnconfigure(0, weight=1)
root.mainloop()
Result:
When the window is resized:
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 write a application where i will get the size of the screen and then resize GUI to take full screen accordingly.
Also, i have 3 frames inside that application. The three frames will have separate widgets. Now based on the screen size available i would like to change the layout of the widgets a bit and also the size of text and wrap length of the texts.
I understood that frame will not have proper size until it have a widget, so i am adding dummy canvas widget. But then also the width of the frames are not getting proper. Am i not doing the thing properly ? If you run the below code frame 1 and frame 2 are having same widths even though visually they are not at all same.
import tkinter as tk
from win32api import GetSystemMetrics
class MainApplication:
def __init__(self):
self.root = tk.Tk()
self.width = GetSystemMetrics(0)
self.height = GetSystemMetrics(1)
self.root.geometry('{}x{}'.format(self.width, self.height))
frame1 = tk.Frame(self.root,bg='blue')
frame1.grid(row=0, column=0, sticky="nsew",rowspan=2)
self.root.grid_columnconfigure(0, weight=5000)
frame1.grid_rowconfigure(0,weight=1)
frame1.grid_columnconfigure(0,weight=1)
self.canvas = tk.Canvas(frame1,bg='blue')
self.canvas.grid(row=0, column=0, sticky="nsew")
self.canvas.update()
print(frame1.winfo_reqwidth())
self.frame2 = tk.Frame(self.root,bg='red')
self.root.grid_columnconfigure(1, weight=1)
self.frame2.grid(row=0, column=1, sticky="nsew")
self.frame2.grid_rowconfigure(0, weight=1)
self.frame2.grid_columnconfigure(0, weight=1)
self.canvas1 = tk.Canvas(self.frame2,bg='red')
self.canvas1.grid(row=0, column=0, sticky="nsew")
self.canvas1.update()
print(self.frame2.winfo_reqwidth())
self.frame3 = tk.Frame(self.root, bg='green')
self.frame3.grid(row=1,column=1,sticky="nsew")
self.root.grid_rowconfigure(1,weight=5000)
self.frame3.grid_rowconfigure(0, weight=1)
self.frame3.grid_columnconfigure(0, weight=1)
self.canvas2 = tk.Canvas(self.frame3,bg='green')
self.canvas2.grid(row=0, column=0, sticky="nsew")
self.canvas2.update()
self.root.mainloop()
if __name__ == '__main__':
a = MainApplication()
I've created a simple GUI application with Tkinter.
I have two questions about this code:
import tkinter as tk
from tkinter import ttk, Grid, Frame, N, S, W, E, StringVar, Label, Entry, RAISED, Button, Checkbutton, Scrollbar
class mainApp(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.scan_button = Button(self.parent, text="Scan", command=self.scan_wifi)
self.forget_button = Button(self.parent, text="Forget", command=self.forget_wifi)
self.reboot_button = Button(self.parent, text="Reboot", command=self.reboot)
frame=Frame(self.parent)
Grid.rowconfigure(self.parent, 0, weight=1)
Grid.columnconfigure(self.parent, 0, weight=1)
frame.grid(row=0, column=0, sticky=N+S+E+W)
grid=Frame(self.parent)
grid.grid(sticky=N+S+E+W, column=0, row=7, columnspan=2)
Grid.rowconfigure(self.parent, 7, weight=1)
Grid.columnconfigure(self.parent, 0, weight=1)
headings=('Name', 'Address', 'Quality', 'Channel', 'Signal Level', 'Encryption')
row=[]
rows=[]
self.table = ttk.Treeview(show="headings", selectmode="browse")
self.table["columns"]=headings
self.table["displaycolumns"]=headings
for head in headings:
self.table.heading(head, text=head, anchor=tk.CENTER)
self.table.column(head, width=30, anchor=tk.CENTER)
self.scrolltable = tk.Scrollbar(command=self.table.yview)
self.table.configure(yscrollcommand=self.scrolltable.set)
self.scrolltable.grid(row=1, column=100, sticky=N+S)
for row in rows:
self.table.insert('', tk.END, values=tuple(row))
self.table.bind('<ButtonRelease-1>', self.OnRelease)
self.table.grid(row=0, rowspan=14, columnspan = 21, sticky=N+S+E+W)
self.scan_button.grid(row=15, column = 1, columnspan = 1, sticky=N+S+E+W)
self.forget_button.grid(row=15, column = 0, columnspan = 1 , sticky=N+S+E+W)
self.reboot_button.grid(row=15, column = 3, columnspan = 1 , sticky=N+S+E+W)
def OnRelease(self, event):
pass
def scan_wifi(self):
pass
def forget_wifi(self):
pass
def reboot(self):
pass
root=tk.Tk()
app = mainApp(root)
root.mainloop()
1) How I can move the button on the top of the window?
2) Why, if I resize the window, the button "Forget" becomes bigger than other buttons? How I can make all buttons identical size?
Because you have called columnconfigure(0, weight=1) only, therefore only the Forget button will be resized when the window is resized.
To move the buttons to the top of the window, you need to rearrange the buttons to row=0 and the Treeview to row=1. Below is modified code based on yours:
import tkinter as tk
from tkinter import ttk
class mainApp(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
# buttons
self.forget_button = tk.Button(self.parent, text='Forget', command=self.forget_wifi)
self.scan_button = tk.Button(self.parent, text='Scan', command=self.scan_wifi)
self.reboot_button = tk.Button(self.parent, text='Reboot', command=self.reboot)
self.forget_button.grid(row=0, column=0, sticky='nsew')
self.scan_button.grid(row=0, column=1, sticky='nsew')
self.reboot_button.grid(row=0, column=2, sticky='nsew')
# make the 3 buttons same width
for i in range(3):
self.parent.columnconfigure(i, weight=1)
# make the treeview and the scrollbar to fill the remaining space
self.parent.rowconfigure(1, weight=1)
# treeview and scrollbar
frame = tk.Frame(self.parent)
frame.grid(row=1, column=0, columnspan=3, sticky='nsew')
headings=('Name', 'Address', 'Quality', 'Channel', 'Signal Level', 'Encryption')
self.table = ttk.Treeview(frame, show='headings', selectmode='browse')
self.table['columns'] = headings
self.table['displaycolumns'] = headings
for head in headings:
self.table.heading(head, text=head, anchor=tk.CENTER)
self.table.column(head, width=30, anchor=tk.CENTER)
self.scrolltable = tk.Scrollbar(frame, command=self.table.yview)
self.table.configure(yscrollcommand=self.scrolltable.set)
self.table.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
self.scrolltable.pack(side=tk.RIGHT, fill=tk.Y)
self.table.bind('<ButtonRelease-1>', self.OnRelease)
def OnRelease(self, event):
pass
def scan_wifi(self):
pass
def forget_wifi(self):
pass
def reboot(self):
pass
root=tk.Tk()
app = mainApp(root)
root.mainloop()
Why doesn't the scrollbar initiate when create_window frame objects start to exceed the bottom self.container window?
My understanding is that widgets are scrollable if they are embedded on the canvas using create_window. For context, I don't want to create a scrolling frame - put all your widget in a frame, use create_window to add that frame to the canvas - because I intend to move these frame objects around on the canvas and leverage a lot of canvas capabilities. According to Effbot, You cannot draw other canvas items on top of a widget., so if I had a scrolling frame, I wouldn't be able to put widgets on top of that.
So how do I scroll the canvas that contains many create_window objects, or, what am I doing wrong below?
import tkinter as tk
class Canvas_Scrollbar_CreateWindow(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.parent.columnconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
self.block_count = 0
self.button = tk.Button(self, text='Add', command=self.addblock)
self.button.grid(row=0, column=0, columnspan=2, sticky='new')
self.container = tk.Frame(self)
self.container.grid(row=1, column=0, sticky='nsew')
self.canvas = tk.Canvas(self.container, width=200, height=450)
self.scrollbar = tk.Scrollbar(self.container,
orient='vertical',command=self.canvas.yview)
self.canvas.config(yscrollcommand=self.scrollbar.set)
self.canvas.grid(row=0, column=0, sticky='nsew')
self.scrollbar.grid(row=0, column=1, sticky='nse')
self.container.bind('<Configure>', self.handle_scroll)
def addblock(self):
self.block = tk.Frame(self.canvas, bd=1, relief='solid')
self.block.columnconfigure(0, weight=1)
self.canvas.create_window((0, (self.block_count*25)),
window=self.block, anchor="nw",
width=200, height=24)
self.block_count += 1
def handle_scroll(self, event):
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
root = tk.Tk()
app = Canvas_Scrollbar_CreateWindow(root)
app.grid(row=0, column=0, sticky='ew')
root.mainloop()
You must re-configure scrollregion when you add items to the canvas.