Dominic Sham
Dominic Sham

Reputation: 307

tkinter pack() method not working for one label

import tkinter as tk

win = tk.Tk()
win.title('使用者登入')
win.geometry('300x200')

lb1 = tk.Label(win,text='使用者帳號資料',font=('微軟正黑體',16),fg='yellow',bg='black')
lb1.pack(fill='x')

lb2 = tk.Label(win,text='帳號 : ABCDEF',height=4,width=26,font=('標楷體',14),bg='lightblue')
lb2.pack(side='left',anchor='nw',fill='x')

lb3 = tk.Label(win,text='注意',height=50,width=3,font=('微軟正黑體',12),bg='pink')
lb3.pack(anchor='se',fill='y',expand=True)

lb4 = tk.Label(win,text='密碼 : 123456',height=4,width=15,font=('標楷體',14),bg='lightgreen')
lb4.pack(anchor='sw',side='left')

win.mainloop()

tkinter window

The variable lb4 could not be shown on the tkinter window even though I have used pack() method. I would like to put the lb4 widget below lb2 and I had tried using anchor='sw' still not showing so any possible methods to have that widget be shown properly?

Upvotes: 1

Views: 2134

Answers (3)

Bryan Oakley
Bryan Oakley

Reputation: 385830

Each time you use pack, it allocates an entire side for the widget. Thus, the order in which you call pack matters. For example, once you put widget along the top, you can no longer put something to the right.

This is usually much easier to visualize when you group all of your pack statements together for all children in the same parent widget. I also recommend always explicitly defining the side parameter so that your intentions are crystal clear.

This is the proper order to use pack to get lb4 below lb2, with lb1 along the top and lb3 along the right side:

lb1.pack(side="top", fill='x')
lb3.pack(side="right", fill='y')
lb2.pack(side="top", fill='x')
lb4.pack(side="top", fill='x')

enter image description here

Upvotes: 1

Dorian Turba
Dorian Turba

Reputation: 3735

The pack method works properly, check that:

import tkinter as tk

win = tk.Tk()
win.title('使用者登入')
win.geometry('300x200')

# lb1 = tk.Label(win,text='使用者帳號資料',font=('微軟正黑體',16),fg='yellow',bg='black')
# lb1.pack(fill='x')
#
# lb2 = tk.Label(win,text='帳號 : ABCDEF',height=4,width=26,font=('標楷體',14),bg='lightblue')
# lb2.pack(side='left',anchor='nw',fill='x')
# 
# lb3 = tk.Label(win,text='注意',height=50,width=3,font=('微軟正黑體',12),bg='pink')
# lb3.pack(anchor='se',fill='y',expand=True)

lb4 = tk.Label(win,text='密碼 : 123456',height=4,width=15,font=('標楷體',14),bg='lightgreen')
lb4.pack(anchor='sw',side='left')

win.mainloop()

tkinter windows

If it does show anything is because the pack method add widget to the right of the previous on if it's anchored to "S"(outh), even if the new widget it's anchored to 'w' and sided to 'left'.

Since lb3 is anchor at 'se', any other widget is displayed outside the windows.

You shoud use .grid to properly design your window:

import tkinter as tk

win = tk.Tk()
win.title('使用者登入')

lb1 = tk.Label(win, text='使用者帳號資料', font=('微軟正黑體', 16), fg='yellow',
               bg='black')
lb1.grid(row=0, column=0, columnspan=3, sticky='WE')

lb2 = tk.Label(win, text='帳號 : ABCDEF', height=4, width=26, font=('標楷體', 14),
               bg='lightblue')
lb2.grid(row=1, column=0, sticky='WE')

lb3 = tk.Label(win, text='注意', width=3, font=('微軟正黑體', 12), bg='pink')
lb3.grid(row=1, column=2, rowspan=2, sticky='NS')
#
lb4 = tk.Label(win, text='密碼 : 123456', height=4, width=15, font=('標楷體', 14),
               bg='lightgreen')
lb4.grid(row=2, column=0, sticky='w')

win.mainloop()

It looks like this:

window with grid

Here, I removed the height of lb3 since it's not required (sticky 'NS' allow us to extend the widget to top and down of the rowspan). You can change column, row, columnspan, rowspan as you want to create the layout you desire.

Upvotes: 2

Devansh10
Devansh10

Reputation: 69

I tried running your code and using lb4 before lb3 fixes the problem, but it won't display below lb2 as you have already used side='left' in lb2 so it acquires the whole left side, to pack it below lb2 remove the side='left' in lb2 and put it in lb4.


It doesn't display lb4 at first because it packs it outside of the TKinter window .

Instead of using .pack() use .grid() to better place the labels in the window.

This works:

import tkinter as tk

win = tk.Tk()
win.title('使用者登入')
win.geometry('300x200')

lb1 = tk.Label(win,text='使用者帳號資料',font=('微軟正黑體',16),fg='yellow',bg='black')
lb1.pack(fill='x')

lb2 = tk.Label(win,text='帳號 : ABCDEF',height=4,width=26,font=('標楷體',14),bg='lightblue')
lb2.pack(anchor='nw',fill='x')

lb4 = tk.Label(win,text='密碼 : 123456',height=4,width=15,font=('標楷體',14),bg='lightgreen')
lb4.pack(side='left',anchor='sw')

lb3 = tk.Label(win,text='注意',height=50,width=3,font=('微軟正黑體',12),bg='pink')
lb3.pack(anchor='se',fill='y',expand=True)

win.mainloop()

enter image description here

Upvotes: 0

Related Questions