Align buttons and labels in each row with Tkinter

Viewed 190

My code:

import tkinter

class latinwords:
    def __init__(self):
        self.main = tkinter.Tk()
        self.top = tkinter.Frame(self.main)
        self.mid = tkinter.Frame(self.main)
        
        self.latinword1 = tkinter.Button(self.mid, text = 'sinister', command = self.cbfunction)
        self.latinword2 = tkinter.Button(self.mid, text = 'dexter', command = self.cbfunction2)
        self.latinword3 = tkinter.Button(self.mid, text = 'medium', command = self.cbfunction3)
        
        self.toplabel = tkinter.Label(self.top, text= 'Latin')              
        self.toplabel2 = tkinter.Label(self.top, text= '\tEnglish')

        self.value = tkinter.StringVar()
        self.value1 = tkinter.StringVar()
        self.value2 = tkinter.StringVar()

        self.labels = tkinter.Label(self.bot, textvariable = self.value)
        self.labels1 = tkinter.Label(self.bot, textvariable = self.value1)
        self.labels2 = tkinter.Label(self.bot, textvariable = self.value2)
        self.labels.pack()
        self.labels1.pack()
        self.labels2.pack()
        
        
        self.top.pack()
        self.mid.pack()
        self.latinword1.pack()
        self.latinword2.pack()
        self.latinword3.pack()
        
        self.toplabel.pack(side='left')
        self.toplabel2.pack(side='left')
        tkinter.mainloop()
        
    def cbfunction(self):
        value = 'left'
        self.value1.set(value)
    def cbfunction2(self):
        value = 'right'
        self.value.set(value)
    def cbfunction3(self):
        value = 'centre'
        self.value2.set(value)
        


s = latinwords()

Unexpected output:

enter image description here

Expected output:

enter image description here

As you can see, I am trying to get my expected output with 3 buttons that can show the English word after its being pressed. But I got my output vertically with my own code. I am expecting my button and the matched word are on same horizontal level. Can anyone help me with this issue? Thanks.

2 Answers

Solution:

  1. The self.bot attribute is missing.

    self.bot = tkinter.Frame(self.main)
    
  2. You should set the position of packing of frames.

    self.top.pack(side=tkinter.TOP)
    self.mid.pack(side=tkinter.LEFT)
    self.bot.pack(side=tkinter.RIGHT)
    

Test/Output:

>>> python3 test.py

GUI

NOTE:

  1. The order of English words are not correct but it is not related to question.
  2. I recommend to use the grid instead of pack. You can make more nice GUI with grid in your case. See more: https://tkdocs.com/tutorial/grid.html

It is better to put all the labels and buttons in same frame and use grid() instead of pack():

import tkinter

class latinwords:
    def __init__(self):
        self.main = tkinter.Tk()

        self.mid = tkinter.Frame(self.main)
        self.mid.pack()
        
        self.latinword1 = tkinter.Button(self.mid, text='sinister', command=self.cbfunction)
        self.latinword2 = tkinter.Button(self.mid, text='dexter', command=self.cbfunction2)
        self.latinword3 = tkinter.Button(self.mid, text='medium', command=self.cbfunction3)
        
        self.toplabel = tkinter.Label(self.mid, text='Latin')              
        self.toplabel2 = tkinter.Label(self.mid, text='English')

        self.value = tkinter.StringVar()
        self.value1 = tkinter.StringVar()
        self.value2 = tkinter.StringVar()

        self.labels = tkinter.Label(self.mid, textvariable=self.value)
        self.labels1 = tkinter.Label(self.mid, textvariable=self.value1)
        self.labels2 = tkinter.Label(self.mid, textvariable=self.value2)
        self.labels.grid(row=1, column=1)
        self.labels1.grid(row=2, column=1)
        self.labels2.grid(row=3, column=1)
        
        self.latinword1.grid(row=1, column=0)
        self.latinword2.grid(row=2, column=0)
        self.latinword3.grid(row=3, column=0)
        
        self.toplabel.grid(row=0, column=0)
        self.toplabel2.grid(row=0, column=1)

        tkinter.mainloop()
        
    def cbfunction(self):
        value = 'left'
        self.value.set(value)

    def cbfunction2(self):
        value = 'right'
        self.value1.set(value)

    def cbfunction3(self):
        value = 'centre'
        self.value2.set(value)

s = latinwords()
Related