Home > Back-end >  How to fix positioning of labels in tkinter?
How to fix positioning of labels in tkinter?

Time:03-09

So I am trying to have a GUI for my Converter (it is intentionally meant to go up to 255 aka 8bits) And I have got it to work on the button layout as planned. But to make it more user-friendly I wanted to put a 'Convert From' label/text above the buttons. However, as soon as I shifted the buttons down a row it didn't go as planned and after careful examination of it. I have got nowhere.

image reference of how it looks without label above the buttons (row = 0)

image reference of how it looks with the label above the buttons as you can see it takes it off screen and out of uniform (row = 1)

#Converter GUI

#importing necessary libaries 
import tkinter
import tkinter.ttk
import tkinter.messagebox
import sys


#defining the types of conversion 
def bin2den(value):
    if len(value) != 8: #checks that it has a length of 8 binary digits 
        return "None"
    return int(value, 2)

def bin2hex(value):
    if len(value) != 8: #checks that it has a length of 8 binary digits
        return "None"
    Ox = hex(int(value, 2))[2:].upper()
    Ox = Ox.zfill(2)
    return Ox

def bin2bin(value):
    if len(value) != 8: #checks that it has a length of 8 binary digits
        print("Invalid input, 8 bits required!")
        return "None"
    return value.zfill(8)

def den2bin(value):
    if int(value) > 255 or int(value) < 0:
        return "None"
    Ob = bin(int(value))[2:]#removing the ob prefix 
    filled = Ob.zfill(8) #filling it to become an 8 bit binary if worth less than 8 bits
    return filled

def den2hex(value):
    if int(value) > 255 or int(value) < 0:
        return "None"
    Ox = hex(int(value))[2:].upper() #removing the ox prefix and capitalising the hex output
    Ox = Ox.zfill(2)#filling the output if not double digits
    return Ox

def den2den(value):
    if int(value) > 255 or int(value) < 0:
        print("Out Of Range")
        return "None"
    return value
    

def hex2bin(value):
    while len(value) != 2 and len(value) > 2: #checking if hex value outside of ff
        return "None"
    Ob = bin(int(value, 16))[2:] #removing the ob prefix 
    Ob = Ob.zfill(8)#filling binary to be 8bits if value is below 8 bits
    return Ob

def hex2den(value):
    while len(value) != 2 and len(value) > 2: #checking if hex value outside of ff
        return "None"
    return int(value, 16)

def hex2hex(value):
    while len(value) != 2 and len(value) > 2: #checking if hex value outside of ff
        print("Invalid input, try again")
        return "None"
    value = value.upper() #capitaliseing for formality
    return value

def readFile(fileName):
    fileObj = open(fileName, "r")#opens file in read only mode 
    HexArray = fileObj.read().splitlines()#puts file into an array
    fileObj.close()
    return HexArray

#setting main window class
#and defining main attributes of the window
class MainWindow():
    
    FONT = ("Consolas", 16)
    TxtMaxLen = 32
    
    def __init__(self):
        self._window = tkinter.Tk()
        self._window.title("Converter")
        #self._window.geometry("800x240") redundant as set below due to positioning 
        self._window["bg"] = "#20A3FF" #background colour
        self._window.resizable(False, False) #stops the window being resized

        windowWidth = self._window.winfo_reqwidth()
        windowHeight = self._window.winfo_reqheight()
 
        # Gets both half the screen width/height and window width/height
        positionRight = int(self._window.winfo_screenwidth()/2 - windowWidth/2)-330
        positionDown = int(self._window.winfo_screenheight()/2 - windowHeight/2)-200
        
        self._window.geometry(f"{windowWidth}x{windowHeight} {positionRight} {positionDown}")
        self._window.geometry("800x240")#setting window size
        
        
        label = tkinter.Label(self._window, text="Number: ", font=MainWindow.FONT)#label defined for number input box 
        label.grid(row=0, column=0, padx=10, pady=5)#positioning / dimensions of input box
        
        self._txt_input = tkinter.Entry(self._window, width=MainWindow.TxtMaxLen, font=MainWindow.FONT) #defined input box 
        self._txt_input.grid(row=0, column=1, pady=5)#postioning / dimensions of input box
        self._txt_input.focus()

        #this is the label that is just runining it 
        #label = tkinter.Label(self._window, text="Convert From ", font=MainWindow.FONT)
        #label.grid(row=0, column=2, padx=5, pady=5)#positioning / dimensions of input box
        
        #following 6 bits of code when row = 0 it works fine but when shifted down a row it goes wrong 
        self._bt_bin = tkinter.Button(self._window, text="Bin", font=MainWindow.FONT, command=self.BinSelection)#button defined for bin  
        self._bt_bin.grid(row=0, column=2, padx=5, pady=5)#postioning / dimensions of button box
        
        self._bt_den = tkinter.Button(self._window, text="Den", font=MainWindow.FONT, command=self.DenSelection)#button defined for den
        self._bt_den.grid(row=0, column=4, padx=5, pady=5)#postioning / dimensions of button box
        
        self._bt_hex = tkinter.Button(self._window, text="Hex", font=MainWindow.FONT, command=self.HexSelection)#button defined for bin
        self._bt_hex.grid(row=0, column=6, padx=5, pady=5)#postioning / dimensions of button box
            
        separator = tkinter.ttk.Separator(self._window,orient=tkinter.HORIZONTAL)
        separator.grid(row=1, column=1, pady=4)

        #setting the Output boxes and the labels accordingly
        #binary output box and label
        label = tkinter.Label(self._window, text="Binary:", font=MainWindow.FONT)#label defined for number box 
        label.grid(row=2, column=0,  padx=10, pady=5)
        
        self._stringvar_bin = tkinter.StringVar()
        txt_output = tkinter.Entry(self._window, textvariable=self._stringvar_bin, width=MainWindow.TxtMaxLen, state="readonly", font=MainWindow.FONT)#entry box set to readonly to act as a display box 
        txt_output.grid(row=2, column=1, pady=5)

        #denary output box and label
        label = tkinter.Label(self._window, text="Denary:", font=MainWindow.FONT)#label defined for number box 
        label.grid(row=3, column=0,  padx=5, pady=5)
        
        self._stringvar_den = tkinter.StringVar()
        txt_output = tkinter.Entry(self._window, textvariable=self._stringvar_den, width=MainWindow.TxtMaxLen, state="readonly", font=MainWindow.FONT)
        txt_output.grid(row=3, column=1, pady=5)

        #hexadecimal output box and label
        label = tkinter.Label(self._window, text="Hexadecimal:", font=MainWindow.FONT)#label defined for number box 
        label.grid(row=4, column=0,  padx=5, pady=5)
        
        self._stringvar_hex = tkinter.StringVar()
        txt_output = tkinter.Entry(self._window, textvariable=self._stringvar_hex, width=MainWindow.TxtMaxLen, state="readonly", font=MainWindow.FONT)
        txt_output.grid(row=4, column=1, pady=5)
        
        
    def BinSelection(self):
        try:
            Bin = self._txt_input.get().strip().replace(" ", "")
            BinValue = bin2bin(Bin)
            DenValue = bin2den(Bin)
            HexValue = bin2hex(Bin)
            
            self._set_values(BinValue, DenValue, HexValue)
            
        except Exception as ex:
            tkinter.messagebox.showerror("Error", "Invalid conversion")
            tkinter.messagebox.showinfo("Error", "Enter a valid 8 bit binary number or a integer / hexadecimal value")
            print(ex, file=sys.stderr)
    
    def DenSelection(self):
        try:
            Den = self._txt_input.get().strip().replace(" ", "")
            DenValue = den2den(Den)
            BinValue = den2bin(Den)
            HexValue = den2hex(Den)
            
            self._set_values(BinValue, DenValue, HexValue)
            
        except Exception as ex:
            tkinter.messagebox.showerror("Error", "Invalid conversion")
            print(ex, file=sys.stderr)
        
    def HexSelection(self):
        try:
            Hex = self._txt_input.get().strip().replace(" ", "")
            HexValue = hex2hex(Hex)
            BinValue = hex2bin(Hex)
            DenValue = hex2den(Hex)
            
            self._set_values(BinValue, DenValue, HexValue)
        
        except Exception as ex:
            tkinter.messagebox.showerror("Error", "Invalid conversion")
            print(ex, file=sys.stderr)
    
    def _set_values(self, BinValue, DenValue, HexValue):
        if not BinValue.startswith(""):
            BinValue = ""   BinValue
        if not HexValue.startswith(""):
            HexValue = ""   HexValue
        
        self._stringvar_bin.set(BinValue)
        self._stringvar_den.set(DenValue)
        self._stringvar_hex.set(HexValue)
    
    def mainloop(self):
        self._window.mainloop()


if __name__ == "__main__":
    win = MainWindow()
    win.mainloop()

any insight on how to fix this would be great thanks. and sorry if this whole question was just a silly one.

CodePudding user response:

Answer to my question as the Issue is now resolved. Fixed it using columnspan which allows you to set a box across several columns.

label = tkinter.Label(self._window, text="Convert From ", font=MainWindow.FONT)
        label.grid(row=0, column=2,columnspan=3, padx=5, pady=5)

Here is what it looks like with the resolved problem enter image description here

  • Related