I am trying to make a start menu for a search engine. I am trying to have buttons and other widgets appear next to labels. This is my code:
class Application(tk.Tk): #subclass Tk
'''Does most of the handling.'''
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.title("Academic Search")
self.geometry("1000x600")
self.resizable(width=True,height=True)
self.start = Start(self)
self.start.grid(sticky=(tk.E + tk.W + tk.N + tk.S))
self.update_button = ttk.Button(self, text="Update Database", command=self.to_database)
self.update_button.grid(row=0,column=0,sticky=tk.W)
self.cc_button = ttk.Button(self, text="Find Common Citations",command=self.to_cc)
self.cc_button.grid(row=1, column=0, sticky=tk.W)#, pady=20)
self.search_button = ttk.Button(self, text="Search", command=self.search)
self.search_button.grid(row=2, column=2, sticky=(tk.E))
class Start(tk.Frame): #subclass of Frame
'''The start window'''
def __init__(self, parent, *args, **kwargs): #takes same args as parent
'''Initializes start window.'''
super().__init__(parent, *args, **kwargs) #calls superclass constructor
query = tk.StringVar()
self.num_return = tk.IntVar()
cw = tk.DoubleVar()
cd = tk.IntVar()
graph = tk.BooleanVar()
jstor = tk.BooleanVar()
self.mb_text = tk.StringVar()
self.mb_text.set('Search multiple DOIs')
self.num_return = tk.IntVar()
self.search_box = ttk.Entry(parent, text='Enter one DOI:',textvariable=query)
self.multiple_button = ttk.Button(self, textvariable=self.mb_text,command=self.to_mult)
self.lbl = ttk.Label(self,text='Enter one DOI.')
self.num_return_lbl = ttk.Label(self, text='Maximum number of records returned:')
self.num_return_box = ttk.Entry(parent, textvariable=self.num_return)
self.cw_lbl = ttk.Label(self, text='Citation weight (must be between 0 and 1):')
self.cw_box = ttk.Spinbox(parent, from_=0, to=1, increment=0.01,textvariable=cw)
self.cd_lbl = ttk.Label(self, text='Maximum citation distance (runtime will increase dramatically if greater than 3):')
self.cd_box = ttk.Spinbox(parent, from_=1, to=10,increment=1, textvariable=cd)
self.jstor_button = ttk.Checkbutton(parent, text='Use JSTOR (requires JSTOR Labs token)',command=jstor)
self.graph_box = ttk.Checkbutton(parent, text='Graph', variable=graph)
self.add_widgets()
def add_widgets(self):
'''Adds widgets to grid.'''
self.lbl.grid(row=2, column=1, sticky=tk.E)
self.cw_lbl.grid(row=3, column=1, sticky=tk.E)
self.cw_box.grid(row=3, column=2, sticky=tk.E)
self.cd_lbl.grid(row=4, column=1, sticky=tk.E)
self.cd_box.grid(row=4, column=2, sticky=tk.E)
self.num_return_lbl.grid(row=5, column=1, sticky=tk.E)
self.num_return_box.grid(row=5, column=2, sticky=tk.E)
self.search_box.grid(row=2, column=2, sticky=(tk.E+tk.W))
self.graph_box.grid(row=6, column=2, sticky=tk.E)
self.jstor_button.grid(row=7, column=2, sticky=tk.E)
self.multiple_button.grid(row=9, column=0, sticky=(tk.W+tk.N))
Why aren't the labels in line with the other elements (Spinboxes, check buttons, entries) when they are in the same row?
This is what it looks like when I do mainloop()
:
The buttons and the labels have different parents, which is why they appear in different locations.
You can see this very clearly if you give the Start
frame a distinctive color. For example, change how you create Start
to be like this:
self.start = Start(self, background="red")
You will end up with a window that looks like this:
Look at the first argument in each of these two lines of code. One uses self
and one uses parent
. self
and parent
are two different widgets.
self.cw_lbl = ttk.Label(self, ...)
self.cw_box = ttk.Spinbox(parent, ...)
Everywhere you use parent
as the parent of a widget in Start
, you should change it to self
. For example, the above code needs to be changed to:
self.cw_box = ttk.Spinbox(self, ...)