1

I am really frustrated, trying to align a label and entry buttons in tkinter. I wanted to create a GUI like below

enter image description here

The above page developed using page tool. I written a code to get the same kind of page, but it has lot of misalignment.

from Tkinter import *
root = Tk()
root.title("Nokia Performance")
root.geometry("583x591+468+158")
root.title("NOKIA _ANSI Performance")
root.configure(borderwidth="1")
root.configure(relief="sunken")
root.configure(background="#dbd8d7")
root.configure(cursor="arrow")
root.configure(highlightbackground="#d9d9d9")
root.configure(highlightcolor="black")


Label1 = Label(root)
_img1 = PhotoImage(file="C:\\Users\\vkandhav\\Desktop\\PY_IMAGE\\NOKIA.gif")
Label1.configure(image=_img1)
Label1.configure(text='''Label''')
Label1.pack()

Label2 = Label(root)
Label2.configure(text='''Enter the platform :''')
Label2.pack(side=LEFT)

Entry2 = Entry(root)
Entry2.pack(side = RIGHT)

Label3 = Label(root)
Label3.configure(text='''Device  IP Address :''')
Label3.pack()

Entry5 = Entry(root)
Entry5.pack()

Label5 = Label(root)
Label5.configure(text='''Username :''')
Label5.pack()

Label6 = Label(root)
Label6.configure(text='''Label''')
Label6.pack()

Label7 = Label(root)
Label7.configure(text='''Craft IP :''')
Label7.pack()

Label8 = Label(root)
Label8.configure(text='''GICCI IP :''')
Label8.pack()

Label9 = Label(root)
Label9.configure(text='''Password :''')
Label9.pack()

Label10 = Label(root)
Label10.configure(text='''STC File Location''')
Label10.pack()

Label11 = Label(root)
Label11.configure(text='''STC Port :''')
Label1.pack()

Label12 = Label(root)
Label12.configure(text='''STC IP :''')
Label2.pack()


Entry6 = Entry(root)
Entry6.configure(background="white")
Entry6.configure(foreground="#000000")
Entry6.pack()

Entry7 = Entry(root)
Entry7.configure(background="white")
Entry7.pack()

Entry8 = Entry(root)
Entry8.configure(background="white")
Entry8.pack()

Entry9 = Entry(root)
Entry9.configure(background="white")
Entry9.configure(foreground="#000000")
Entry9.pack()

Entry10 = Entry(root)
Entry10.configure(background="white")
Entry10.configure(foreground="#000000")
Entry10.pack()

Entry11 = Entry(root)
Entry11.configure(background="white")
Entry11.configure(foreground="#000000")
Entry11.pack()

Radiobutton1 = Radiobutton(root)
Radiobutton1.configure(justify=LEFT)
Radiobutton1.configure(text='''NRNT-A''')
Radiobutton1.pack()

Radiobutton2 = Radiobutton(root)
Radiobutton2.configure(justify=LEFT)
Radiobutton2.configure(text='''SX-12VP''')
Radiobutton2.pack()

Radiobutton3 = Radiobutton(root)
Radiobutton3.configure(justify=LEFT)
Radiobutton3.configure(text='''DX-48''')
Radiobutton3.pack()

Radiobutton4 = Radiobutton(root)
Radiobutton4.configure(justify=LEFT)
Radiobutton4.configure(text='''SX-16VP''')
Radiobutton4.pack()

Radiobutton5 = Radiobutton(root)
Radiobutton5.configure(justify=LEFT)
Radiobutton5.configure(text='''SX-16F''')
Radiobutton5.pack()

Radiobutton6 = Radiobutton(root)
Radiobutton6.configure(justify=LEFT)
Radiobutton6.configure(text='''FX-8''')
Radiobutton6.pack()

Button1 = Button(root)
Button1.configure(pady="0")
Button1.configure(text='''NEXT''')
Button1.pack()
mainloop()
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
velpandian
  • 431
  • 4
  • 11
  • 23
  • 1
    Why struggle with pack? That's clearly a grid type layout(at least in the manner you're creating widgets). – Nae Feb 27 '18 at 11:36
  • even i tried with grid, still i didn't get output like i expected. – velpandian Feb 27 '18 at 11:43
  • I think it would be best if you can group the widgets you use in some way. What are the widgets that have something(ideally multiple) things in common? Then create a class that has those common things. I think for example you have a common duo, which is label + entry, I'd probably create a class for that and initiate it with only the distinct parts. There are multiples of that label + entry type object, hence a collection type may be useful such as a list or a dictionary. – Nae Feb 27 '18 at 11:43
  • I think the way you structure your code, what best suits you is `place`. That's only a workaround for bad structuring in the above case though. – Nae Feb 27 '18 at 11:50
  • Ok thanks Nae for your suggestion. As per my understanding using place we can place our frames or entry based on X, Y position. Is that correct? – velpandian Feb 27 '18 at 12:00
  • Yes, but that's not as scalable as the other two options. – Nae Feb 27 '18 at 12:00
  • I created a code like below, `from Tkinter import * root=Tk() root.geometry("900x650+220+20") page1=Frame(root) Entry1=Entry(page1) Entry1.place(x=400, y = 150)` In this case i don't see any output, may i know why? `Entry1=Entry(root) Entry1.place(x=400, y = 150)` In this case i see output, may i know how it's happening – velpandian Feb 27 '18 at 12:10
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165897/discussion-between-nae-and-velpandian). – Nae Feb 27 '18 at 12:51
  • 1
    @Nae: `place` is almost never the right answer. This is especially true here, where `grid` is the obvious choice. – Bryan Oakley Feb 27 '18 at 12:54
  • @BryanOakley I agree but I was concerned that creating the exact layout with the exact given widgets using grid would be too hard(take a look at the radio buttons for example). Hence, while I wouldn't use place here myself, I think one needs to use place or write the code above from scratch with better code structure, at which point it wouldn't really matter if pack or grid was used. – Nae Feb 27 '18 at 13:22
  • @nae: I don't understand your "too hard" comment. It's trivial. The only difficult part is the radiobuttons, and that's trivial too. Just put them in a small frame, and the whole frame goes in one cell. – Bryan Oakley Feb 27 '18 at 13:37
  • @BryanOakley True, but that's modifying the structure. If adding widgets for layout reasons then it's trivial to achieve the same layout with pack as well. But that's stepping into rewriting the code, hence I reached my concl. of _"Rewrite the entire thing with better struct.(at which point it should be trivial to have a layout using both grid or pack), or have a quick fix using place(which is while easier to understand not exactly the long-term solution)."_ I figured if OP wanted to learn the long-term solution they'd ask more of a conceptual question ins. of which I think to be an exact one. – Nae Feb 27 '18 at 13:57
  • @Nae: _"If adding widgets for layout reasons then it's trivial to achieve the same layout with pack as well. "_ - I would argue that's a false statement. `pack` is more difficult than `grid` when it comes to creating a uniform grid. That's one of the reasons `grid` was created (tk for years only had `pack` and `place`). To create a grid with `pack` means you have to manually calculate identical widths and heights of the items in a consistent fashion. – Bryan Oakley Feb 27 '18 at 14:38
  • @BryanOakley Hmm, I see. But how do you classify the layout above as a uniform grid? I mean I don't precisely understand what you mean by that but, couldn't one just encapsulate the label + entry pairs in frames(like with radiobuttons) and pack to top of another encapsulating frame for example? Or is there a particularly bad case in the above layout for pack? – Nae Feb 27 '18 at 14:48
  • 1
    @Nae: _"But how do you classify the layout above as a uniform grid?"_ because I can draw a series of horizontal and veritical lines, and everything is aligned along those lines. _" couldn't one just encapsulate the label + entry pairs in frames(like with radiobuttons) and pack to top of another encapsulating frame for example?"_ - yes, but you have to make sure that the widths of the left and right sides of those frames are identical to the widths of the other items. It can be done, but it's tedious. `grid` can take care of all of that for you. – Bryan Oakley Feb 27 '18 at 15:26

1 Answers1

7

You are clearly creating a grid of widgets, so I recommend using grid. It's well documented and easy to use.

These types of layouts are easiest if you group all of your layout code together rather than interlacing it with your widget creation.

I'm not going to rewrite your whole program, but here's the general idea:

from Tkinter import *

root = Tk()
root.geometry("600x200")

root.grid_columnconfigure((0,1), weight=1)

Label3 = Label(root, text="Device IP Address")
Label4 = Label(root, text="Username")
Label5 = Label(root, text="Password")

Entry3 = Entry(root)
Entry4 = Entry(root)
Entry5 = Entry(root)

Label3.grid(row=3, column=0)
Entry3.grid(row=3, column=1, sticky="ew")
Label4.grid(row=4, column=0)
Entry4.grid(row=4, column=1, sticky="ew")
Label5.grid(row=5, column=0)
Entry5.grid(row=5, column=1, sticky="ew")

root.mainloop()

The above code creates this window:

screenshot

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Thank you Bryan, I want to keep a image in top of that then need some space between the image and "Device IP Address" (First row). Is that possible to achieve anyway ? Can you explain what is use of grid_columnconfigure – velpandian Feb 27 '18 at 14:21
  • 1
    @velpandian: yes, it's all possible. Read the documentation to get an answer to what `grid_columnconfigure` does. There's nothing special about adding images or groups of radiobuttons or anything else. It's all documented and there are many examples on the net. – Bryan Oakley Feb 27 '18 at 14:36
  • It looks a good candidate to create each field group in a loop. – Jaime Lopez Feb 12 '23 at 01:08