0

I'm making a simple tkinter UI to get user input to run a script. I've made UIs like this before, but for some reason this time the grid() method creates overlapping widgets. I double-checked to ensure that each widget has a unique row and column within its parent frame. The two label frames I have don't show their label either.

root = tk.Tk()

# Frame for input options
inputFr = tk.Frame(root)
inputFr.grid(row=1,column=0)

# variable for excel book to import
xlBookVar = tk.StringVar()

# variables for spreadsheet columns
serialNumberColVar = tk.StringVar()
apNameColVar = tk.StringVar()
apControllerColVar = tk.StringVar()
switchNameColVar = tk.StringVar()
portNumberColVar = tk.StringVar()
displayStrColVar = tk.StringVar()
descriptionColVar = tk.StringVar()

# other variables
ignoredRowsVar = tk.IntVar()

tk.Label(inputFr,text="Excel Book Name: ").grid(row=1,column=0,sticky='W')
tk.Entry(inputFr,textvariable=xlBookVar).grid(row=1,column=1)
tk.Label(inputFr,text="ignored rows from top: ").grid(row=2,column=0,sticky='W')
tk.Entry(inputFr,textvariable=ignoredRowsVar).grid(row=2,column=1)

apNameFr = tk.LabelFrame(inputFr,text="AP Name").grid(row=3,column=0,columnspan=2)
tk.Label(apNameFr,text="Serial Number column: ").grid(row=1,column=0,sticky='WE')
tk.Entry(apNameFr,textvariable=serialNumberColVar).grid(row=1,column=1,sticky='WE')
tk.Label(apNameFr,text="AP name Column: ").grid(row=2,column=0,sticky='WE')
tk.Entry(apNameFr,textvariable=apNameColVar).grid(row=2,column=1,sticky='WE')
tk.Label(apNameFr,text="AP controller Column: ").grid(row=3,column=0,sticky='WE')
tk.Entry(apNameFr,textvariable=apControllerColVar).grid(row=3,column=1,sticky='WE')

portDesFr = tk.LabelFrame(inputFr,text="Port Description").grid(row=4,column=1,columnspan=2,sticky='NESW')
tk.Label(portDesFr,text="Switch Name column: ").grid(row=1,column=0,sticky='WE')
tk.Entry(portDesFr,textvariable=switchNameColVar).grid(row=1,column=1,sticky='WE')
tk.Label(portDesFr,text="Port number column: ").grid(row=2,column=0,sticky='WE')
tk.Entry(portDesFr,textvariable=portNumberColVar).grid(row=2,column=1,sticky='WE')
tk.Label(portDesFr,text="display String column: ").grid(row=3,column=0,sticky='WE')
tk.Entry(portDesFr,textvariable=displayStrColVar).grid(row=3,column=1,sticky='WE')
tk.Label(portDesFr,text="description String column: ").grid(row=4,column=0,sticky='WE')
tk.Entry(portDesFr,textvariable=descriptionColVar).grid(row=4,column=1,sticky='WE')

tk.Button(root,text="Run",command=Run).grid(row=2,column=0)

root.mainloop()

Here is the output:

Tkinter Output

Here is the structure that I'm trying to achieve:

  • {Input Frame}
    • Excel Book Name: __
    • Ignored rows from top: __
    • {apNameFr} ap name
      • Serial Number column: __
      • etc..
    • {portDesFr} Port Description
      • Switch Name column: __
      • etc ..
  • {button} Run
cweb
  • 382
  • 2
  • 11
  • You can't use ` = tk.LabelFrame(...).grid(...)` use ` = tk.LabelFrame(...)` and `.grid(...)` instead. – TheLizzard May 21 '21 at 20:40
  • 1
    Your problem is very similar to this one: [Tkinter: AttributeError: NoneType object has no attribute ](https://stackoverflow.com/questions/1101750/tkinter-attributeerror-nonetype-object-has-no-attribute-attribute-name) – TheLizzard May 21 '21 at 20:41
  • well, tkinter won't overlap your widgets if you let it arrange them by itself with `.pack`, instead of manually picking rows and columns with `.grid`, and using overlapping coordinates. – jsbueno May 21 '21 at 20:48
  • @jsbueno So instead of the widgets overlapping you will have to create a bunch of frames and they aren't going to be placed correctly anyways because of the mistke OP made – TheLizzard May 21 '21 at 20:55
  • oh, they will be placed correctly. It is only that with the mistake of trying to assing the return of `.grid` (or `.pack` for that case) to a variable, the OP won't be _able_ to access the widgets. But they will be in place! – jsbueno May 21 '21 at 21:21
  • @jsbueno while it's true that `pack` won't overlap widgets by design, it's not a suitable replacement for `grid` if you are in fact creating a grid of widgets. – Bryan Oakley May 21 '21 at 23:43
  • Ok, thanks guys. I got lazy and tried to create widgets without assigning them to variables since I wouldn't need to reference them later. I added dummy variables and moved all my .grid() calls to a new line. – cweb May 22 '21 at 05:02

1 Answers1

1

I'm not sure what was going on, but I think what caused it was creating the frames and calling grid in the same line. Below is a working code:

import tkinter as tk

root = tk.Tk()

# Frame for input options
inputFr = tk.Frame(root)
inputFr.grid(row=1,column=0, columnspan=2)

# variable for excel book to import
xlBookVar = tk.StringVar()

# variables for spreadsheet columns
serialNumberColVar = tk.StringVar()
apNameColVar = tk.StringVar()
apControllerColVar = tk.StringVar()
switchNameColVar = tk.StringVar()
portNumberColVar = tk.StringVar()
displayStrColVar = tk.StringVar()
descriptionColVar = tk.StringVar()

# other variables
ignoredRowsVar = tk.IntVar()

tk.Label(inputFr,text="Excel Book Name: ").grid(row=1,column=0,sticky='W')
tk.Entry(inputFr,textvariable=xlBookVar).grid(row=1,column=1)
tk.Label(inputFr,text="ignored rows from top: ").grid(row=2,column=0,sticky='W')
tk.Entry(inputFr,textvariable=ignoredRowsVar).grid(row=2,column=1)

# apNameFr = tk.LabelFrame(root,text="AP Name").grid(row=2,column=0,columnspan=2)
apNameFr = tk.LabelFrame(root,text="AP Name")
apNameFr.grid(row=2,column=0,columnspan=2)
tk.Label(apNameFr,text="Serial Number column: ").grid(row=1,column=0,sticky='WE')
tk.Entry(apNameFr,textvariable=serialNumberColVar).grid(row=1,column=1,sticky='WE')
tk.Label(apNameFr,text="AP name Column: ").grid(row=2,column=0,sticky='WE')
tk.Entry(apNameFr,textvariable=apNameColVar).grid(row=2,column=1,sticky='WE')
tk.Label(apNameFr,text="AP controller Column: ").grid(row=3,column=0,sticky='WE')
tk.Entry(apNameFr,textvariable=apControllerColVar).grid(row=3,column=1,sticky='WE')
#
portDesFr = tk.LabelFrame(root,text="Port Description")
portDesFr.grid(row=4,column=0,columnspan=2,sticky='NESW')
tk.Label(portDesFr,text="Switch Name column: ").grid(row=1,column=0,sticky='WE')
tk.Entry(portDesFr,textvariable=switchNameColVar).grid(row=1,column=1,sticky='WE')
tk.Label(portDesFr,text="Port number column: ").grid(row=2,column=0,sticky='WE')
tk.Entry(portDesFr,textvariable=portNumberColVar).grid(row=2,column=1,sticky='WE')
tk.Label(portDesFr,text="display String column: ").grid(row=3,column=0,sticky='WE')
tk.Entry(portDesFr,textvariable=displayStrColVar).grid(row=3,column=1,sticky='WE')
tk.Label(portDesFr,text="description String column: ").grid(row=4,column=0,sticky='WE')
tk.Entry(portDesFr,textvariable=descriptionColVar).grid(row=4,column=1,sticky='WE')

def Run():
    pass

tk.Button(root,text="Run",command=Run).grid(row=6,column=0)

root.mainloop()

Maybe someone else can explain us why the widgets overlap on that situation.

  • You __did__ change the columns and rows used in some of the widgets in this example - they were overlapping because you were putting them in the same place.For example, both the "ignored rows from top: " label in the start and the "Run" button where at "row=2, column=0" in the snippet included with the question, but in this answer, the Button is properly relocated to row=6. – jsbueno May 21 '21 at 20:51
  • But changing the columns and rows alone did not fix the overlapping issue. – Felipe Martins May 21 '21 at 21:26