Python Tkinter frame newby geometry problem? - python

I am very new in tkinter and python. Thats how my code looks:
import tkinter as tk
main = tk.Tk()
# Window size
main.geometry("400x700")
main.resizable(0, 0)
# Window position
w = main.winfo_reqwidth()
h = main.winfo_reqheight()
ws = main.winfo_screenwidth()
hs = main.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
main.geometry('+%d+%d' % (x, y))
fr1 = tk.Frame(main, borderwidth=2, relief="solid", bg = "#271ee3", width=400, height=50)
fr2 = tk.Frame(main, borderwidth=2, relief="solid", bg = "#0d9467", width=200, height=650)
fr3 = tk.Frame(main, borderwidth=2, relief="solid", bg = "#3e1854", width=200, height=650)
fr1.pack()
fr2.pack(side="left")
fr3.pack(side="right")
main.mainloop()
With this code I get the
following window
So far so good. The problem comes when i add this code:
# Label
l = tk.Label(fr2, text="Heyho")
l.grid(row=0, column=0)
Now it looks so
My goal is to get a window where i have in the first frame (fr1) a button that has the same geometry like fr1. In fr2 und fr3 I want to have severel labels among each other. My labels in fr2 und fr3 should have column 0 but ascending rows (0,1,2,3...). How can I do it??

It automatically resize Frame to Label's size so you don't see green background which is hidden behind label - and you see main window's gray background.
You can see it better if you add other longer label and red background in main window
If you add
fr2.grid_propagate(False)
then frame will keep its size
but you still have problem with grid which doesn't use full size of Frame and you can't center it or align to right.
If you add
fr2.grid_columnconfigure(0, weight=1)
then column 0 will try to use full size if there is no other columns, and label will be centered in cell
If you use
sticky='we'
in grid() for labels then they will fill cell
import tkinter as tk
main = tk.Tk()
# Window size
main.geometry("400x200")
main.resizable(0, 0)
main['bg'] = 'red'
# Window position
w = main.winfo_reqwidth()
h = main.winfo_reqheight()
ws = main.winfo_screenwidth()
hs = main.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
main.geometry('+%d+%d' % (x, y))
fr1 = tk.Frame(main, borderwidth=2, relief="solid", bg = "#271ee3", width=400, height=50)
fr2 = tk.Frame(main, borderwidth=2, relief="solid", bg = "#0d9467", width=200, height=650)
fr3 = tk.Frame(main, borderwidth=2, relief="solid", bg = "#3e1854", width=200, height=650)
fr1.pack()
fr2.pack(side="left")
fr3.pack(side="right")
fr2.grid_propagate(False)
fr2.grid_columnconfigure(0, weight=1)
l1 = tk.Label(fr2, text="Heyho")
l1.grid(row=0, column=0, sticky='we')
l2 = tk.Label(fr2, text="Hello World")
l2.grid(row=1, column=0, sticky='we')
main.mainloop()

Related

How to align the LabelFrames to left on tkinter?

I am new to tkinter and learning to organize the frames in tkinter.
In the following code, I have created 3 label frames.
The frames are not aligned as per my requirements and I would like to get help organizing them cleanly.
Required
===========
By default it gives me following layout
LabelFrame1 LabelFrame2
LabelFrame3
I would like to have left aligned label frames like this:
LabelFrame1 LabelFrame2
LabelFrame3
How to align all label frames to left so that I can have spaces in right?
MWE
# %%writefile a.py
import tkinter as tk
from tkinter import ttk,messagebox
# variables
padding = dict(padx=20,pady=20)
padding_widget = dict(padx=10,pady=5)
# root app
win = tk.Tk()
w,h = 800, 600 # app
ws, hs = win.winfo_screenwidth(), win.winfo_screenheight() # screen
x,y = -10,hs*0.1
win.geometry('%dx%d+%d+%d' % (w, h, x, y))
#===================== end of Snippets =====================================
# Frame contains labelframes
f = tk.Frame(win,height=200, width=200)
f.grid(row=0,column=0,padx=20, pady=20)
f.pack(fill="both", expand="yes")
#=============================================================================
# label frame: Find and Replace
lf00 = tk.LabelFrame(f,text='Find and Replace from Clipboard')
lf00.grid(row=0,column=0,padx=20, pady=20)
b = tk.Button(lf00,text='Click to Replace')
b.grid(row=2,column=0,sticky='news',**padding)
#=============================================================================
# label frame: Text Manipulation
lf01 = tk.LabelFrame(f,text='Text Manipulation')
lf01.grid(row=0,column=1,padx=20, pady=20)
b = tk.Button(lf01,text='Click to Replace')
b.grid(row=2,column=0,sticky='news',**padding)
#=============================================================================
# LabelFrame: Calculator
lf10 = tk.LabelFrame(f,text='Calculator')
lf10.grid(row=1,column=0,padx=10, pady=10)
l_exp = tk.Label(lf10,text="Expression")
t_i = tk.Text(lf10, height=2, width=70, bg="light yellow", padx=0,pady=0)
t_o = tk.Text(lf10, height=4, width=40, bg="light cyan",padx=0,pady=0)
b_calc = tk.Button(lf10,height=1,width=10,text="Calculate")
l_exp.pack();t_i.pack();b_calc.pack();t_o.pack()
# Main window
win.config()
win.mainloop()
Update
# %%writefile a.py
import tkinter as tk
from tkinter import ttk,messagebox
# variables
padding = dict(padx=20,pady=20)
padding_widget = dict(padx=10,pady=5)
# root app
win = tk.Tk()
w,h = 800, 600 # app
ws, hs = win.winfo_screenwidth(), win.winfo_screenheight() # screen
x,y = -10,hs*0.1
win.geometry('%dx%d+%d+%d' % (w, h, x, y))
#===================== end of Snippets =====================================
# Frame contains labelframes
f = tk.Frame(win,height=200, width=200)
f.grid(row=0,column=0,padx=20, pady=20,sticky="w")
f.pack(fill="both", expand="yes")
#=============================================================================
# label frame: Find and Replace
lf00 = tk.LabelFrame(f,text='Find and Replace from Clipboard')
lf00.grid(row=0,column=0,padx=20, pady=20,sticky="w")
b = tk.Button(lf00,text='Click to Replace')
b.grid(row=2,column=0,sticky='w',**padding)
#=============================================================================
# label frame: Text Manipulation
lf01 = tk.LabelFrame(f,text='Text Manipulation')
lf01.grid(row=0,column=1,padx=20, pady=20,sticky="w")
b = tk.Button(lf01,text='Click to Replace')
b.grid(row=2,column=0,sticky='w',**padding)
#=============================================================================
# LabelFrame: Calculator
lf10 = tk.LabelFrame(f,text='Calculator')
lf10.grid(row=1,column=0,padx=10, pady=10,sticky="w")
l_exp = tk.Label(lf10,text="Expression")
t_i = tk.Text(lf10, height=2, width=70, bg="light yellow", padx=0,pady=0)
t_o = tk.Text(lf10, height=4, width=40, bg="light cyan",padx=0,pady=0)
b_calc = tk.Button(lf10,height=1,width=10,text="Calculate")
l_exp.pack();t_i.pack();b_calc.pack();t_o.pack()
# Main window
win.config()
win.mainloop()
For greater clarity, first draw on a piece of paper what you want to place in the window. Like this:
And you will see that you need to stretch tk.LabelFrame(f, text='Calculator') over several cells ( columnspan=3).
import tkinter as tk
from tkinter import ttk, messagebox
# variables
padding = dict(padx=20, pady=20)
padding_widget = dict(padx=10, pady=5)
# root app
win = tk.Tk()
w, h = 800, 600 # app
ws, hs = win.winfo_screenwidth(), win.winfo_screenheight() # screen
x, y = -10, hs * 0.1
win.geometry('%dx%d+%d+%d' % (w, h, x, y))
# ===================== end of Snippets =====================================
# Frame contains labelframes
f = tk.Frame(win, height=200, width=200)
f.grid(row=0, column=0, padx=20, pady=20)
f.pack(fill="both", expand="yes")
f.columnconfigure(1, weight=1)
# =============================================================================
# label frame: Find and Replace
lf00 = tk.LabelFrame(f, text='Find and Replace from Clipboard')
lf00.grid(row=0, column=0, padx=(20, 2), pady=20, sticky='e')
b = tk.Button(lf00, text='Click to Replace')
b.grid(row=0, column=0, sticky='nswe', **padding)
# =============================================================================
# label frame: Text Manipulation
lf01 = tk.LabelFrame(f, text='Text Manipulation')
lf01.grid(row=0, column=1, padx=2, pady=20, sticky='w')
b = tk.Button(lf01, text='Click to Replace')
b.grid(row=0, column=0, sticky='nswe', **padding)
# =============================================================================
# LabelFrame: Calculator
lf10 = tk.LabelFrame(f, text='Calculator')
lf10.grid(row=1, column=0, columnspan=3, padx=20, pady=20, sticky='w')
l_exp = tk.Label(lf10, text="Expression")
t_i = tk.Text(lf10, height=2, width=70, bg="light yellow", padx=0, pady=0)
t_o = tk.Text(lf10, height=4, width=40, bg="light cyan", padx=0, pady=0)
b_calc = tk.Button(lf10, height=1, width=10, text="Calculate")
l_exp.pack()
t_i.pack()
b_calc.pack()
t_o.pack()
# Main window
win.config()
win.mainloop()

Click to open a new canvas panel with an image- tkinter

Hi I want to click on a picture in the canvas in order to open a new canvas in which there is another picture and for some reason the new canvas opens and the picture does not appear anyone might know how to fix this?
from tkinter import *
from PIL import Image, ImageTk
root = Tk()
root.title("root")
root.geometry('800x550')
canvas = Canvas(root,
bg='white',
bd=5,
relief='groove',
height=500,
width=700,
)
canvas.place(x=80, y=0)
def press_to_open(event):
x, y = event.x, event.y
print('{}, {}'.format(x, y))
new_img = Image.open("images/back_p.png")
w, h = new_img.size
if x >= 3 and x <= 3 + w and y >= 3 and y <= 3 + h:
canvas2 = Canvas(canvas,
bg='white',
bd=2,
relief='groove',
height=120,
width=250,
)
canvas2.place(x=100, y=90)
resize_text = Label(canvas2, text="Resize the image:", bg="white", font=('Bodoni MT',
12))
resize_text.place(x=65, y=10)
img = PhotoImage("images/x.png")
x_button = Button(canvas2, command=canvas2.destroy, bd=0, image=img)
x_button.pack()
canvas2.create_window(10, 10, window=x_button, height=65, width=65)
def destroy_window(event):
global new_label
new_label.destroy()
color_img = ImageTk.PhotoImage(Image.open("images/back_p.png"))
label = Label(canvas, image=color_img)
label.place(x=10, y=10)
root.bind('<Button-1>', press_to_open)
root.bind('<Button-3>', destroy_window)
root.mainloop()

Python tkinker resitze Canvas

I have an Python3 Tkinter Programm. I have 3 Frames in the Main Window and in one Frame an canvas with scroll Option - now i want resitze the Canvas Area .
Now if i resize it moves the Scroll Bar for Y out the Window and the scrollbar for x works also not as expected (get bigger but slide area don't change)
How i Mange it to resize an Canvas in an grid Layout - The Window must be the same size , the Scrollbas must be updatet and the Canvas Plane must be bigger.
an excerpt from my code:
import tkinter as tk
def menu_build():
caninfo[0] += 10
cangui.configure(width = caninfo[0])
#cangui.configure(scrollregion=cangui.bbox("all"))
def gui():
master = tk.Tk()
master.title( "Easy Switch" )
master.geometry("480x320")
frametop = tk.Frame(master, bg="blue", bd=2)
frametop.grid(column=0,row=0)
frameex = tk.Frame(master, bg="yellow", bd=2)
frameex.grid(column=1,row=1)
framegui = tk.Frame(master, bg="red", bd=2)
framegui.grid(column=0, columnspan=2, row=1)
menu = tk.Menu(master)
master.config(menu=menu)
filemenu = tk.Menu(menu)
menu.add_cascade(label="Config", menu=filemenu)
filemenu.add_command(label="Resize",command=menu_build)
global cangui
cangui = tk.Canvas(framegui, width=385, height=250)
#caninfo = [385,250]
cangui.grid(row=1, column=2)
scroll_x = tk.Scrollbar(framegui, orient="horizontal", command=cangui.xview)
scroll_x.grid(row=2, column=2, sticky="ew")
scroll_y = tk.Scrollbar(framegui, orient="vertical", command=cangui.yview)
scroll_y.grid(row=1, column=3, sticky="ns")
cangui.configure(yscrollcommand=scroll_y.set,xscrollcommand=scroll_x.set)
cangui.configure(scrollregion=cangui.bbox("all"))
cwcb = tk.Checkbutton(framegui, text="ccw").grid(row=2,column=0)
cangui.create_arc(90,90,110,110,style=tk.PIESLICE,width=4,start=0,extent=300)
master.mainloop()
global caninfo
caninfo = [385,250]
if __name__ == "__main__":
gui()
no need to resize the canvas Area
wrote an extra funktion
win = [int(cangui.cget("width")),int(cangui.cget("height"))]
draw_xy = cangui.bbox("all")
swin = (min(0,draw_xy[0]),min(0,draw_xy[1]),max(draw_xy[2],win[0]),max(draw_xy[3],win[1]))
cangui.configure(scrollregion=swin)
reason: canvas.bbox("all") gives only the positon from most upper/left grafic and i want 0/0

How to align text input on Tkinter grid

I'm sure it's a quick fix, but I just can't seem to figure out how to align my entry text boxes (in column 4) with the images & buttons in (columns 1-3). Here is my code, and an image of actual verse desired output:
I've tried changing the column and row position of t1 - t3 (CHAPTER NUMBER INPUTS) but they still appear shifted below the other grid "boxes" instead of in the same row.
from tkinter import *
from tkinter import ttk
# pip install pillow
# from pillow import Image, ImageTk
from PIL import ImageTk, Image
WD = Tk() # window
FM = Frame(WD) # frame
FM.grid(row=0,column=0)
# LABELS
lblA = Label(FM, text="Image 1", font=("Arial Bold", 20))
lblB = Label(FM, text="Image 2", font=("Arial Bold", 20))
lblC = Label(FM, text="Image 3", font=("Arial Bold", 20))
# LABEL POSITIONS
lblA.grid(row=0, column=1)
lblB.grid(row=1, column=1)
lblC.grid(row=2, column=1)
# CHAPTER NUMBER INPUTS
#ch1 = ""
t1 = Text()
t2 = Text()
t3 = Text()
# t1.config(wrap=WORD)
# t2.config(wrap=WORD)
# t3.config(wrap=WORD)
#ch1_entry = Entry(FM, width=8, textvariable=ch1)
t1.grid(row=0, column=4)#, sticky=(S, W))
t2.grid(row=1, column=4)#, sticky=(S, W))
t3.grid(row=2, column=4)#, sticky=(S, W))
# BUTTONS
btnA1 = Button(FM, text ="Move Up")
btnA2 = Button(FM, text ="Move Down")
btnB1 = Button(FM, text ="Move Up")
btnB2 = Button(FM, text ="Move Down")
btnC1 = Button(FM, text ="Move Up")
btnC2 = Button(FM, text ="Move Down")
# BUTTON POSITIONS
btnA1.grid(row=0,column=2, sticky="n")
btnA2.grid(row=0,column=2, sticky="s")
btnB1.grid(row=1,column=2, sticky="n")
btnB2.grid(row=1,column=2, sticky="s")
btnC1.grid(row=2,column=2, sticky="n")
btnC2.grid(row=2,column=2, sticky="s")
# IMAGES
load1 = Image.open("parrot.jpg")
renderA = ImageTk.PhotoImage(load1)
renderB = ImageTk.PhotoImage(load1)
renderC = ImageTk.PhotoImage(load1)
imgA = Label(FM, image=renderA)
imgB = Label(FM, image=renderB)
imgC = Label(FM, image=renderC)
imgA.image = renderA
imgB.image = renderB
imgC.image = renderC
# IMAGE POSITIONS
imgA.grid(row=0, column=3)
imgB.grid(row=1, column=3)
imgC.grid(row=2, column=3)
#root = Tk()
#app = Window(root)
#root.wm_title("Tkinter window")
#root.geometry("400x120")
WD.mainloop()
The images, buttons, and label are children of FM but the text widgets are children of root. If you want the text widgets aligned with everything else then they also need to be children of FM
t1 = Text(FM)
t2 = Text(FM)
t3 = Text(FM)
If you want the image to control the height of a row, you can give the text widget a height of 1 and then use the sticky attribute to cause it to expand to fill the height created by the image.
t1 = Text(FM, height=1)
t2 = Text(FM, height=1)
t3 = Text(FM, height=1)
...
t1.grid(row=0, column=4, sticky="nsew")
t2.grid(row=1, column=4, sticky="nsew")
t3.grid(row=2, column=4, sticky="nsew")

tkinter insert widget in a frame

I am trying to make the following layout
tkinter layout
but the ID: label and the entry box are center left , and center right when then they should be next to each other , and they keep getting separated by the grid
I am also trying to use a for loop to make the number pad but im not sure how to make a new variable outside of the loops, and increment by 1 in the loop that creates the button
from tkinter import *
window = Tk()
#BOTTOM FRAME SECTION
bottomframe = Frame(window,bg="cyan", width =900, height = 100)
bottomframe.pack(fill=BOTH,side=BOTTOM)
button = Button(window,text="LOG IN")
button.pack(fill=BOTH,side=BOTTOM)
checkbutton = Checkbutton(window, text="Use pseudonym?")
checkbutton.pack(side=BOTTOM)
topframe = Frame(window,bg="red",width =900, height = 100)
topframe.pack(fill=BOTH,side=TOP)
label1 = Label(window, text="Majestic 12 Identifier")
label1.pack(side=TOP)
label2 = Label(window, text="ID")
label2.pack(side=LEFT)
label3 = Label(window,text="Enter keycode:")
label3.pack(side=TOP)
entry1 = Entry(window)
entry1.pack(side=LEFT)
#GRID SECTION
frame = Frame(window)
frame.pack(fill=BOTH,side=BOTTOM)
n = +1
for i in range(3):
Grid.rowconfigure(frame,i,weight=1)
Grid.columnconfigure(frame,i,weight=1)
for i in range(3):
b = Button(frame, text="%d" % (i+n))
for j in range(3):
b = Button(frame, text="%d" % (j+1))
b.grid(row=i, column=j,ipadx=2,ipady=2,padx=2,pady=2,sticky= W+E+N+S)
window.mainloop()
any help is welcome
Ok, I gave it a try. I played around a bit with the Frame objects. I deleted one, that was not needed. And I introduced topframe2 in order to make it possible for label2 and entry1 to be in the same row.
Watch carefully the parent of the various entries and labels. Not everything should get the window object as direct parent.
I am using expand and fill arguments - here I am basically applying what I just learned at Textbox not expanding with containing frame - TKinter and tkinter gui layout using frames and grid
from tkinter import *
window = Tk()
# BOTTOM FRAME SECTION
topframe = Frame(window, width=900, height=100)
topframe.pack(fill=BOTH, side=TOP)
label1 = Label(topframe, text="Majestic 12 Identifier")
label1.pack(side=TOP, fill=BOTH, expand=1)
topframe2 = Frame(topframe, width=900, height=100)
topframe2.pack(fill=BOTH, side=TOP)
label2 = Label(topframe2, text="ID")
label2.pack(side=LEFT)
entry1 = Entry(topframe2)
entry1.pack(side=LEFT, fill=X, expand=1)
label3 = Label(window, text="Enter keycode:")
label3.pack(side=TOP)
# GRID SECTION
frame = Frame(window)
frame.pack(fill=BOTH, side=TOP, expand=1)
n = +1
for i in range(3):
Grid.rowconfigure(frame, i, weight=1)
Grid.columnconfigure(frame, i, weight=1)
for i in range(3):
b = Button(frame, text="%d" % (i + n))
for j in range(3):
b = Button(frame, text="%d" % (j + 1))
b.grid(row=i, column=j, ipadx=2, ipady=2, padx=2, pady=2, sticky=W + E + N + S)
button = Button(window, text="LOG IN")
button.pack(fill=BOTH, side=BOTTOM)
checkbutton = Checkbutton(window, text="Use pseudonym?")
checkbutton.pack(side=BOTTOM)
if __name__ == '__main__':
window.mainloop()

Categories