Sam.Natale
Sam.Natale

Reputation: 50

Having frames next to each other in Tkinter

Basically I want to place a clock at one side of the screen and text at the other, I use frames. How can I do this. Here's a picture of what it looks like now:

I want to make it so the clock is in line with the text on the same row but seperate labels. Take a look at my code and see if you could help me in someway, please!

from tkinter import *
from tkinter import ttk
import time

root = Tk()
root.state("zoomed")  #to make it full screen

root.title("Vehicle Window Fitting - Management System")
root.configure(bg="grey80")

Title = Frame(root, width=675, height=50, bd=4, relief="ridge")
Title.pack(side=TOP, anchor='w')
titleLabel = Label(Title, font=('arial', 12, 'bold'), text="Vehicle Window Fitting - Management System", bd=5, anchor='w')
titleLabel.grid(row=0, column=0)

clockFrame = Frame(root, width=675, height=50, bd=4, relief="ridge")
clockFrame.pack(side=TOP, anchor='e')
clockLabel = Label(clockFrame, font=('arial', 12, 'bold'), bd=5, anchor='e')
clockLabel.grid(row=0, column=1)
curtime = ""

def tick():
    global curtime
    newtime = time.strftime('%H:%M:%S')
    if newtime != curtime:
        curtime = newtime
        clockLabel.config(text=curtime)
    clockLabel.after(200, tick)
tick()

Bottom = Frame(root, width=1350, height=50, bd=4, relief="ridge")
Bottom.pack(side=TOP)


root.mainloop()

Upvotes: 0

Views: 16326

Answers (3)

martineau
martineau

Reputation: 123463

One issue is trying to mix the pack and grid layout managers as they don't play well together. Below is something that just uses pack. (Note you can use either one within a frame, just not both at the same time.)

To get the two items on the same "line", another Frame named topFrame has been added and the titleLabel and clockFrame widgets nested inside that. This grouping allows them both to be acted-upon as a single unit when moved or positioned — automatically affecting both of them but retaining their relative positions (LEFT and RIGHT) to one another.

I also removed the curtime global variable because it wasn't really necessary (as you can see by the modified tick() function).

from tkinter import *
from tkinter import ttk
import time

root = Tk()
root.state("zoomed")  #to make it full screen

root.title("Vehicle Window Fitting - Management System")
root.configure(bg="grey80")

topFrame = Frame(root, width=1350, height=50)  # Added "container" Frame.
topFrame.pack(side=TOP, fill=X, expand=1, anchor=N)

titleLabel = Label(topFrame, font=('arial', 12, 'bold'),
                   text="Vehicle Window Fitting - Management System",
                   bd=5, anchor=W)
titleLabel.pack(side=LEFT)

clockFrame = Frame(topFrame, width=100, height=50, bd=4, relief="ridge")
clockFrame.pack(side=RIGHT)
clockLabel = Label(clockFrame, font=('arial', 12, 'bold'), bd=5, anchor=E)
clockLabel.pack()

Bottom = Frame(root, width=1350, height=50, bd=4, relief="ridge")
Bottom.pack(side=BOTTOM, fill=X, expand=1, anchor=S)

def tick(curtime=''):  #acts as a clock, changing the label when the time goes up
    newtime = time.strftime('%H:%M:%S')
    if newtime != curtime:
        curtime = newtime
        clockLabel.config(text=curtime)
    clockLabel.after(200, tick, curtime)

tick()  #start clock
root.mainloop()

Here's what it looks like running:

screenshot

Upvotes: 7

S.G. Harmonia
S.G. Harmonia

Reputation: 297

Use grid(row=x, column=y). It makes adjacent object placing much easier. Also, consider using just one frame for something. You also don't need to specify width, really (unless if you use pack/grid_propagate(0)).

frame_1 = Frame(root, width=675, height=50)
frame_1.pack(side=TOP)

title_lbl = Label(frame_1, text="Lol whateva", height=50, bd=4, font=('arial', 12, 'bold'), relief="ridge", anchor=wherever_you_need_this_to_be)
title_lbl.grid(row=n, column=n)

clock_lbl = Label(clockFrame, font=('arial', 12, 'bold'), bd=5, anchor=wherever_you_need_this_to_be)
clock_lbl.grid(row=n, column=n)

You also didn't need more than one frame, just one frame for each label. It's a bad idea, really and it also consumes more time and typing.

Upvotes: 1

Bryan Oakley
Bryan Oakley

Reputation: 385970

I would create a frame for the header, and use something like header.pack(side="top", fill="x"). Then, I would put the two labels in that frame, packing one to the left and one to the right.

I would then add a second frame to fill the rest of the GUI, and all other widgets would go in that space.

Upvotes: 2

Related Questions