Tkinter Module - Python

 

Tkinter Module in Python

For a better reading experience, check the published document


What is Tkinter anyway?

"Tkinter" is a GUI building tool (Graphical User Interface), that allows us to build desktop applications easily. It has a lot of configurations and widgets that provide us with a wide set of selections to start building.



Installing the Module

This module comes with Python, so no need for further installation.



Importing the Module

from tkinter import * 
from tkinter import ttk, messagebox, filedialog



Creating an initial window .. "walt"

Let's initialize a window by creating its backbone, we're going to name him "walt", or it .. depending on your philosophy.

walt = Tk()       # create walt the window by using the (Tk) instance

# =====================
# our code will be here 
# =====================

walt.mainloop()   # we have to add this line to keep the code looping

Now when we run the code, a window will be popped up. Simple, right?


Within the next chapters, we're going to mention EVERY single detail about how to edit the window's configurations, how to create all kinds of widgets like buttons and texts, and a lot more.



Processes on walt's


Edit walt's configurations

walt.title("Hi, I am walt !")       
# change the title of walt

walt.resizable(0, 1)         
# allow/forbid resizable for (height, width) respectively
# that will prevent walt from resizing the length and allow 
# resizing the width by the user means it is forbidden, 1 is allowed

walt.geometry("320x570")            
# specify the dimensions (length x width) of walt by pixels 
walt.geometry("320x570+200+200")    
# specify where should walt show up (200px, 200px) of the computer's screen 

walt.minsize("100x100")      # specify the minimum possible size of walt
walt.maxsize("500x500")      # specify the maximum possible size of walt

# assign walt as the main window (if we have more than one window)
walt.lift()

# minimize walt to the taskbar
walt.lower()                
walt.state("iconic")
walt.iconify()

# display walt normally
walt.state("normal")   
walt.deiconify()

# hide walt from the user (also from the taskbar)
walt.state("withdrawn")
walt.withdrawn()

# return walt's state currently (normal, iconic, withdrawn)
walt.state()

# close walt
walt.destroy()
walt.quit()


Binding walt with an event

Binding: linking an event (mouse-click or a keyboard button pressed) with an action like calling a particular function

# defining the funcion
def myFun(event):
 	print(hello)

# bind-statement with the left-click 
# we only need to write the name of the function, 
# NOT a calling statement with brackets ()
walt.bind("<Button-1>", myFun ) 

<Button-1> triggered with the left-click

<Button-2> triggered with the middle-click

<Button-3> triggered with the right-click

<Enter> triggered when the cursor enters the widget’s area

<Leave> triggered when the cursor leaves the widget’s area

<FocusIn> triggered when navigating to the widget using the Tab-button

<Return> triggered with the Enter-key after a Tab-navigating

<Key> triggered with any key on the keyboard


Inside the function (myFun), we can get some information about the calling event:

event.x 
# returns x-position of the cursor when triggering the event 
event.y
# returns y-position of the cursor when triggering the event

event.char 
# returns the pressed character on the keyboard (in case of <Key>)

event.keysym 
# returns the key symbol of the pressed character (single one or a hot-key) 



Controller variables for walt

Regular variables can't store real-time values. Real-time data refers to the data that is constantly changing by the user while the app is running. Such as the text in a text field, or the selection of a radio button.

We can use this variable to store these data, reach it, or change it any time at any trigger (pressing a key or a mouse click) while the app is running. We define the type of the variable as we need:

myString = StringVar() 
# create a variable to store string values

myInteger = IntVar() 
# create a variable to store integer values

myBoolean = BooleanVar()
# create a variable to store boolean values

myDouble = DoubleVar()
# create a variable to store double values


We can use the controller as following:

# returns the saved string on the variable 
myString.get() 

# set the value of the variable 
string1.set("hello")

# clear (delete) the value from the variable 
string1.del() 



Widgets for walt

A widget is what we call any tool on walt's canvas. A button, a text-field, a slider, a radio button, a selection bar, ...etc. All those and more, we refer to them as "Widgets". Any widget we want to build has to belong to a window like walt, so we have to specify the name of the desired window when we initialize any widget. Every widget is an instance of a class in Tkinter that has its name (e.g. any button is an instance of the "Button" class).


Properties (options) of widgets:

Widgets have optional like color, font, dimensions, state, ...etc. Be aware that we can specify those for a widget when we initialize it, but we can also change them anytime.


Standard and Specific options of widgets:

All widgets have a set of "Standard Options" that exist in all widgets. Options such as background, font, and text. Every widget has a set of "Specific Options" which are different for each widget. Options such as width, height, and command.


Attaching a widget to walt the window:

We have to go through two main steps to do that successfully:

1) Creating the widget: initialize the instance of its class and specify its host window (e.g. "walt")

2) Specify its geometry: specifying the layout (grid, place, or pack) that holds that widget (how does walt should organize his widgets). We will talk about that in the last chapter


ALWAYS REMEMBER: no widget will appear on any window unless you attach it to that window and add a geometry tool to it. In addition, there are some widgets that have to be attached to other widgets instead of a window. In that case, only the parent widget needs to be attached to a window and have a geometry tool.


The basic structure for any widget:

variable_name = WidgetClass(desired_window, properties*)

variable_name.geometry_type()


Example:

# create the window
walt = Tk()

# create the widget
myText = Text(walt)

# add geometry (attach the widget)
myText.pack()

# close the loop
walt.mainloop()



The Toplevel widget

It is window just like walt, but we can use more options with the Toplevel

# a toplevel belongs to walt
myToplevel = Toplevel(walt) 

# force the (myTopLevel) to inherit all 
# options of the window (walt)
myTopLevel.group(walt) 


Specific options:

background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, menu, relief, screen, takefocus, use, visual, width




The Entry widget

It is an editable text-field so the user can enter a text on it. It MUST have a controller variable to store the text inside it

# create a controller
myString = StringVar()

# create the entry which belong to walt 
myEntry = Entry(walt, textvariable = myString) 

# add a geometry tool 
myEntry.pack()

# returns the string written in the entry by the controller
myEntry.get() 


We have more methods related to the entry widget

# focus the curser on the field 
myEntry.focus_set()

# delete the 4th character from the entry
myEntry.delete(3)
# delete characters from 0 to 3 from the entry
myEntry.delete(0, 3)
# delete everything
myEntry.delete(0, END) : it will  

# insert the text to the entry starting from the index (4)
myEntry.insert(4, "hello")
# insert the text to the entry at the end
myEntry.insert(END, "hello")  

# remove the selection(shade of the text) from the text
myEntry.select_clear() 
# check if the text is selected (returns True or False)
myEntry.select_present() 
# select the text from the index 3 to 8
myEntry.select_range(3, 8) 


Specific options:

background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, invalidcommand, invcmd, justify, relief, selectbackground, selectborderwidth, selectforeground, show, state, takefocus, textvariable, validate, validatecommand, vcmd, width, xscrollcommand




The Button widget

It is simply a clickable button. We can link it with any function using Lambda expression to customize what shall happen if the user click on it by the (command) option

# create the button with its geometry
myButton = Button(walt, command = lambda: print("Clicked !"))
myButton.pack()


Specific options:

command, compound, default, height, overrelief, state, width




The Checkbotton widget

It is a clickable checkbox. A bo that the user can check/uncheck. I must have an integer controller to store the

# create the labeled check button with its controller  
myInteger = IntVar()
myCeckBotton = Checkbotton(walt, text="here", variable = myInteger)
myCeckBotton.pack()

# make the CheckButton flash for a second
myCheckButton.flash()
# check the button
myCheckButton.select() 
# uncheck the button
myCheckButton.deselect()


Specific options:

activebackground, activeforeground, anchor, background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, offvalue, onvalue, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, variable, width, wraplength




The Label widget

It is just a label that has text on it.

# create the label 
myLabel = Label(walt, text="Hello!") 
myLabel.pack()


Specific options:

height, state, width




The Message widget

It is a multi-line and non-editable text. It works the same as the Label except that the Message auto-justifies (or aligns) its text to the left.

myMessage = Message(walt, text = "Fixed text !!!")
myMessage.pack()


Specific options:

None




The Text widget

It is a multi-line editable text.

myText = Text(walt)
myText.pack()

# insert content at the beginning of the text
myText.insert(INSERT, "Starting here,")
# insert content at the end of the text
myText.insert(END, "Ending here.")
# insert the text to the entry at the 3rd line, index (4)
myText.insert(3.4, "hello") 


Specific options:

autoseparators, height, maxundo, spacing1, spacing2, spacing3, state, tabs, undo, width, wrap




The MessageBox widget

MessageBox is a pop-up window that holds information or a question for the user. It has many types of alerts and questions depending on where do you want to use it.

NOTE: This widget doesn't need a geometry because it's floating and doesn't belong to any window

# we must import this class individually to use it
from tkinter import messagebox


msg = messagebox.showinfo("note", "hello there,") 
# shows an alert message that says "hello there," and titled with "note"

msg = messagebox.showwarning("warning", "dont delete that!") 
# shows a warning message
 
msg = messagebox.showerror("error", "invalid")
# shows an error message

msg = messagebox.askquestion("question", "do you have an account ?")
# ask a (yes/no) question and save the answer (yes/no) in (msg)

msg = messagebox.askyesno("question", "do you have an account ?")  
# ask a (True/False) question and save the answer (True/False) in (msg)

msg = messagebox.askokcancel("question", "do you have an account ?")  
# ask a (ok/cancel) question and save the answer (True/False) in (msg)

msg = messagebox.askyesnocancel("question", "do you have an account ?")  
# ask a (yes/no/cancel) question and save the answer (True/False/None) in (msg)

msg = messagebox.askyesnocancel("alert", "command faild")  
# ask a (retry/cancel) question and save the answer (True/False) in (msg)


Specific options:

None




The Menu widget

It is used to create top menues and sub-menues inside walt's space.

NOTE: This widget doesn't need a geometry. Instead, it has to be attached to walt by editing his configuration

# create the main menu (not visible yet)
myMenu = Menu(walt) 

# attach the top-fixed horizontal menu (myMenu) to walt  
# that will only create whitespace at the top, we will fill it after that
walt.config(menu=myMenu) 

# create a new sub menu (not visible yet)
myFileMenu = Menu(walt)

# attach the sub-menu (myFileMenu) to the main menu (myMenu)
# yse the attribute "label" to add atext on it  
myMenu.add_cascade(label="File", menu = myFileMenu) 

# cascade a sub-menu (python) to the sub-menu (myFileMenu)
pythonMenu = Menu(walt)
myFileMenu.add_cascade(label="Python", menu = pythonMenu)

# add a tab labeled as "Print" to the submenu (myFileMenu)
# we can link this tab to a function using lambda to do cusomize its job
myFileMenu.add_command(label="Print", command = lambda: print("hi!")) 

# add a horizontal line (separator) to the menu
myFileMenu.add_separator()  


Specific options:

activebackground, activeborderwidth, activeforeground, background, bd, bg, borderwidth, cursor, disabledforeground, fg, font, foreground, postcommand, relief, selectcolor, takefocus, tearoff, tearoffcommand, title, type




The Radiobutton widget

It is a multi-choice selection tool. It offers several options for the user to choose one or more from them (we can customize it).

# First demo

# create the controller
radioVariable = IntVar()

# create the first button 
myRadioButton1 = Radiobutton(walt, text="1st option", variable=radioVariable, value=1)
myRadioButton1.pack()

# create the second button 
myRadioButton2 = Radiobutton(walt, text="2nd option", variable=radioVariable, value=1)
myRadioButton2.pack()

# that will create two radio buttons, but when we click on one of them, 
# the other will get clicked too because both have the same variable and the same value


# Second demo

radioVariable = IntVar()

myRadioButton1 = Radiobutton(walt, text="1st option", variable=radioVariable2, value=1)
myRadioButton2 = Radiobutton(walt, text="2nd option", variable=radioVariable2, value=2) 
myRadioButton3 = Radiobutton(walt, text="3rd option", variable=radioVariable2, value=3)

myRadioButton1.pack()
myRadioButton2.pack()
myRadioButton3.pack()

# that will create three individual radio buttons, 
# and we can only choose one of them because all have the 
# same variable but not the same value


Specific options:

activebackground, activeforeground, anchor,background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, value, variable, width, wraplength




The Listbox widget (usually used with a Scrollbar widget)

It is a list where the user can select one of its options. We can add as many options as we want.

We have to link it with a string controller variable to store the chosen selection.

# create a string controller
myString = StringVar()

# create the the empty Listbox
myListBox = Listbox(walt, listvariable = myString)
myListBox.pack()

# insert selections to the listbox:
# insert the word "Python" to the listbox at index 0
myListBox.insert(0, 'Python')
# insert at index 1 (after Python)
myListBox.insert(1, 'Java')
# insert at index 1 (before Java)
myListBox.insert(1, 'C++')
# insert at the end 
myListBox.insert(END, 'R')

# returns the number of selections in the listbox
myListBox.size()
# returns all selections as a list
myString.get() 

# returns the selection at index 2 (third one)
myListBox.get(2) 
# returns the current selected selection  
myListBox.get(ANCHOR) 

# delete the selection at index 2 from the listbox 
myListBox.delete(2) 
# delete the current selected selection from the listbox  
myListBox.delete(ANCHOR)   


Specific options:

background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, relief, selectbackground, selectborderwidth, selectforeground, selectmode, setgrid, takefocus, width, xscrollcommand, yscrollcommand, listvariable




The Scrollbar widget (usually used with a ListBox widget)

It is a slide controller which will be used allow scrolling effect for list-widgets like the ListBox.

# create a scroll bar to display a list
myScrollBar = Scrollbar(walt) 

# needed geometry:
# stick it to the right with filling vertically 
# we can fill it vertically(y) or horizontally(x)
# we can stick it to the (RIGHT, LEFT, TOP, or BOTTOM)
myScrollBar.pack(side=RIGHT, fill="y") 

# create the listbox and attach it with the scrollbar
# we can either select "yscrollcommand" and "yview" for a vertical bar (y),
# or "xscrollcommand" and "xview" for a horizontal bar (x),
myList = Listbox(walt, yscrollcommand=myScrollBar.set)
myList.pack(side=RIGHT, fill=Y)
myScrollBar.config(command=myList.yview) 

# fill the desired data inside the listbox
for line in range(100):
    myList.insert(END, "This is line: " + str(line)) 

# ONLY if we want to use grid geometry instead of pack
# we must put both listbox scrollbar in the same cell 
myScrollBar.grid(row=2, column=3)
myList.grid(row=2, column=3)


Specific options:

activebackground, activerelief, background, bd, bg, borderwidth, command, cursor, elementborderwidth, highlightbackground, highlightcolor, highlightthickness, jump, orient, relief, repeatdelay, repeatinterval, takefocus, troughcolor, width




The Scale widget

It provides a slider that allows the user to select any numeric value from it.

# create a horizontal slider scale from 10 to 30 
# we can use either "HORIZONTAL" or "VERTICAL" orientation
myScale = Scale(walt, from_=10, to=30, orient=HORIZONTAL)
myScale.pack()

# returns the current selected number on the scale 
myScale.get()

# set the slider's value to 20
myScale.set(20) 


Specific options:

activebackground, background, bigincrement, bd, bg, borderwidth, command, cursor, digits, fg, font, foreground, from, highlightbackground, highlightcolor, highlightthickness, label, length, orient, relief, repeatdelay, repeatinterval, resolution, showvalue, sliderlength, sliderrelief, state, takefocus, tickinterval, to, troughcolor, variable, width




The Spinbox widget

It is a spinning list with multiple selections where the user can select one of them. Values can be inserted as a numerical range or as a list.

# the string controller 
myString = StringVar()

# we can either fill the spinbox with a numeric range (from 5 to 20)
mySpinBox1 = Spinbox(walt, textvariable=myString, from_=5, to=20)
mySpinBox1.pack() 
# or we can insert them as a list with multiple choices from the values
mySpinBox2 = Spinbox(walt, textvariable=myString, values=["option 1", "option 2", "option 3"])
mySpinBox2.pack()

# return the current selected value
myString.get()  


Specific options:

buttonbackground, buttoncursor, buttondownrelief, buttonuprelief, command, disabledbackground, disabledforeground, format, from, invalidcommand, increment, readonlybackground, state, to, validate, validatecommand values, width, wrap




The Combobox widget

It is a spinning list with multiple selections (exactly like the spin box). The only difference is that the list in this widget can be opened with a scroll effect by the user instead of spinning through options.

# we must import ttk individually to use it
from tkinter import ttk


# the string controller
myString = StringVar()

# insert them as a list with multiple choices from the values
myCombo = ttk.Combobox(walt, textvariable=myString , values=["option 1", "option 2", "option 3"])
myCombo.pack()

# return the current selected value
myString.get()


Specific options:

exportselection, justify, height, postcommand, state, textvariable, values, width




The PannedWindow widget

It is a container widget used to handle number of panes arranged in it

# create a panned window
myPanedWindow = PanedWindow(walt)
myPanedWindow.pack()

# attach widgets to the panned window by the (add) method
myEntry1 = Entry(myPanedWindow)
myPanedWindow.add(myEntry)

# or we can attach widgets using a geometry tool 
myEntry2 = Entry(myPanedWindow)
myEntry2.pack()

# we can cascade panned windows in the same way
subPanedWindow = PanedWindow(myPanedWindow, orient=VERTICAL)
myPanedWindow.add(subPanedWindow) 
# then we can add widgets to it
myLabel = Label(subPanedWindow, text="hi")
subPanedWindow.add(myLabel) 


Specific options:

None




The Frame widget

It is a container that holds widgets. It is used for grouping and organizing widgets, we can also nest frames inside each other.

# create a frame 
myFrame = Frame(walt)
myFrame.pack()

# create a button and attach it to the frame 
myButton = Button(myFrame)
myButton.pack()

# create a sub frame, add it to the main one, 
# then create a button and attach it to the sub frame 
subFrame = Frame(myFrame)
subFrame.pack()
myButton = Button(subFrame)
myButton.pack() 


Specific options:

background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, relief, takefocus, visual, width




The LabelFrame widget

It is a titled frame, and works exactly like the regular frame.

myLabFrm = LabelFrame(walt, text="I'm a container !")
myLabFrm.pack() 


Specific options:

background, class, colormap, container, height, labelanchor, labelwidget, visual, width




The Canvas widget

It is used to draw doodles and other complex layouts like graphics, text and widgets.

# create a canvas on walt
myCanvas = Canvas(walt, height=10, width=10)
myCanvas.pack()

# draw a line starting from (0, 0) to (20, 50)
myCanvas.create_line(0, 0, 20, 50)   # (x1, y1, x2, y2)
# the point (0, 0) as (x, y) is located at the top left corner of the canvas
# increasing x will move the point towards the right
# increasing y will move the point towards the bottom

# draw an arc starting from (0, 0) to (100, 150)
myCanvas.create_line(0, 0, 100, 150)  


Specific options:

 background, bd, bg, borderwidth, closeenough, confine, cursor, height, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, offset, relief, scrollregion, selectbackground, selectborderwidth, selectforeground, state, takefocus, width, xscrollcommand, xscrollincrement, yscrollcommand, yscrollincrement




The PhotoImage widget

It displays a photo imported from a path. The path can be either the name of the photo if it was in the same directory (folder) of the python file. Or we can provide a full or relative path including the name of the photo.

# import the photo if it was in the same 
# directory (folder) of the python file
myPhoto = PhotoImage(file = "myPhto.png")

# import the photo by its relative path
myPhoto = PhotoImage(file = ".\assets\images\myPhto.png")

# import the photo by its full path
myPhoto = PhotoImage(file = "G:\python\project0\assets\images\myPhto.png")

# display it at a label 
labelPhoto = Label(walt, image = myPhoto)
labelPhoto.pack() 


Specific options:

None




The Treeview widget

# we must import ttk individually to use it
from tkinter import ttk


It displays data from lists as a table.

# create the tree view
myTreeview = ttk.Treeview(walt, columns=(1,2,3), show="headings", height=20)
myTreeview.pack()

# defining teh names of the columns 
myTreeview.heading(1, text="Index")
myTreeview.heading(2, text="State")
myTreeview.heading(3, text="score")

# filling the cells
index = range(5)
state = ["done", "not yet", "not yet", "done", "done"]
score = [46, 78, 31, 11, 90]

for i, j, k in zip(index, state, score):
    myTreeview.insert("", "end", values=(i, j, k)) 


Specific options:

columns, displaycolumns, height, padding, selectmode, show




The OptionMenue widget

It is exactly like a combo box, but it has fixed selections and we can’t write inside it.

# define the choices
selections = ["A", "B", "C", "D"]

# create the controller
myString = StringVar()

# create the menu
myOptionMenu = OptionMenu(walt, myString , *selections)
myOptionMenu.pack() 

# set the value of the menu to the third selection
myString.set(selections[2])


Specific options:

None




The Notebook widget

# we must import ttk individually to use it
from tkinter import ttk


It is a big container (like the internet browser) that has multiple frames (like the tabs in the browser) and we can navigate among them to show each one’s contents

# create the notebook 
myNoteBook = ttk.Notebook(walt)
myNoteBook.pack()

# create frames, each one represents an independent tab(page) in the notebook
frame1 = Frame(myNoteBook)
frame2 = Frame(myNoteBook)
frame3 = Frame(myNoteBook)
frame4 = Frame(myNoteBook)

# attach the frames(tabs or pages) to the notebook and give 
# them titles using the (add) method
myNoteBook.add(frame1, text="Frame 1")
myNoteBook.add(frame2, text="Frame 2")
myNoteBook.add(frame3, text="Frame 3") 

# we can use the (insert) method to attach frames at specific indexes   
# insert the 4th frame at index(1) which is between 
# the frame1(index 0) and frame2(had index 1, but now will have index 2)
myNoteBook.insert(1, frame4, text="Frame 4")

# hide the frame at index (2)
myNoteBook.hide(2)

# navigate (go to) to the frame at index (2)
myNoteBook.select(2) 

# adding widgets to any frame we want
myButton = Button(frame1, text="Go to frame 3", command = lambda: myNoteBook.select(2))
myButton.pack() 


Specific options:

height, padding, width




The Dialog box (filedialog) widget

# we must import it individually to use it
from tkinter import filedialog


It is a window that can browse through the device's files and folders to get one of them or more. Actually, it only gets the file's path followed by its name, so we can open it or edit it.

# we have to provide the following parameters:
# initialdir: select the initial directory of the browser wizard
# title: specify the title of the browser wizard 
# filetypes: specify the allowable extensions that the browser wizard can detect 

# browse to get a single file, returns a string 
walt.filename = filedialog.askopenfilename(
        initialdir=r"C:", 
        title="Select a file", 
        filetypes=(("All", "*.*"), ("png file", "*png")))

# print the selected file
print(walt.filename)

# browse to get multiple files, returns a list of strings 
walt.filenames = filedialog.askopenfilenames(
        initialdir=r"C:", 
        title="Select multiple files", 
        filetypes=(("All", "*.*"), ("png file", "*png")))

# print all selected files
for i walt.filenames:
    print(i)



Options for walt's widgets

We have two types of options, "Standard Options" which exist in all widgets, and "Specific Options" which are different for each widget. Options can be defined at the instantiation of the widget, or we can add them in another line to that widget by editing its configuration.


Changing the options of a widget:

After giving options to the widget at its instantiation, we can change or add options to that widget by editing its configuration

# change options by configure 
myEntry.configure(bg="red", width=50)

# return the text on that button 
myButton["text"] 
# change the text on the button 
myButton["text"] = "Click me!"  


Standard Options:


activebackground: (string) the color of the background when the widget is pressed

activeforeground: (string) the color of the font when the widget is pressed

background: (string) the color of the background

foreground: (string) the color of the font

bg: (string) the color of the background - alias

fg: (string) the color of the font - alias

we can assign color values by either writing a valid color name or using a Hexa color:

"red", "darkgreen", "#128af8"


anchor: (string) specify at what side should the contents of the widget align

it can be assigned to any of the following as a string:

(n, s, e, w): basic directions (north, south, east, west)

(ne, nw, se, sw): corners (northeast, northwest, southeast, southwest)

(cen): center


bitmap: (string) replace any text in the widget with a symbol, it can be any of the following strings:

error, gray25, gray50, gray75, hourglass, info, questhead, question, warning


borderwidth: (int) specify the thickness of the widget's border in pixels (you have to activate “relief”)

bd: (int) specify the thickness of the widget's border - alias

relief: (string or pre-defined variables) change the effect of the border

we can choose one of those: ("flat", "sunken", "raised", "groove", "ridge")

or we can select one of the pre-defined (FLAT, SUNKEN, RAISED, GROOVE, RIDGE)


font: (tuple) we have to provide 3 main attributes for the font (‘family’, 'size', ‘extra’)

family: (italic, tahoma, times, …)

size: size of the font as an integer

extra: (bold, underline, italic, overstrike, …)


highlightcolor: (string) change the color of the surrounding border

highlightthikness: (int) change the thickness of the surrounding border


image: (PhotoImage) set the image as the background of the widget


justify: (string) align the text to the left or right ("left", "right") vertically


NOTE: Paddings and Margins: if we put it as an option of the widget, it will be inner padding (a space between the text and the borders of its container). But if we put as an option of the Geometry tool, it will be outer padding or a margin (a space between the widgets) 

padx: (int) add padding along the x-axis of the element

pady: (int) add padding along the y-axis of the element


text: (string) change the text on the widget

underline: (int) add an underline at the entered index for text on the widget

wraplength: (int) limit the length (the margins) of the widget's text to be 100 pixels


cursor: (string) change the symbol of the cursor



Common Options:


width: (int) set the width of the widget

height: (int) set the height of the widget

length: (int) the same as (height), we use this with widgets that don't accept (height)


title: (string) set the title of the widget (for titled widgets)

label: (string) add a label on the widget (for widgets that don’t accept the (text) option)


state: (string) change the state of the widget (normal, active, disabled, readonly)

orient: (string) change the orientation of the widget, "h" for horizontally and "v" for vertically

show: (single character string) displays the text written in the entry as the specified character

like (*), (#), (@), ...etc.


command: (lambda) link the widget with a function that will be triggered once we clicked on the widget, e.g. lambda: print("hello")


textvariable: (stringVar) connects the widget with the string variable

variable: (intVar) used for CheckButtons to connect the widget with the integer variable


selectbackground: (string) change the background's color of the selected text (shaded by the user)

selectforeground: (string) change the font color of the selected text

selectborderwidth: (int) change the width of the shade itself for the selected text

selectmode: (string) only for list widgets, change the mode of selecting items

“single”: select only one item at a time

“multiple”: you can select more than one item at a time


only for CheckButton:

onvalue: (string) change the value of the integer (variable) of the check button if it is checked

offvalue: (string) change the value of the integer (variable) of the check button if it is unchecked


only for widgets with a slider:

sliderlength: (int) change the length of the slider

troughcolor: (string) change the color of the trough (slider's bar)

resolution: (int) change the step of the slider


only for editable text fields:

insertbackground: (string) change the color of the inserting cursor

insertwidth: (int) change the width of the inserting cursor

insertborderwidth: (string) change the width of the border of the inserting cursor

insertontime: (int) change the flashing speed of the inserting cursor

spacing: (int) change the length of the space between each two lines

wrap: (string) make a new line at a certain condition:

"word": whenever the last word in the current line reaches the edge of the widget



Geometry management (organizing widgets)

As we have said before, widgets to be visible on the window must have a geometry tool. We have 3 tools but we can only add one tool for each widget. Also, we have to select the same tool for all widgets at the same container (window, panned window, frame, ...etc.)


We can also use any of the geometry tools to add outer paddings to the widget.


The Pack geometry

It will orient the elements relatively to each other or to their container.

# stick the widget to the center of its parent (default)
button1.pack() 

# stick the widget to a one of the 4 sides of its parent
# we can select one of those strings ("right", "left", "top", "bottom")
# or we can select one of the pre-defined (RIGHT, LEFT, TOP, BOTTOM) 
button1.pack(side=RIGHT)

# expand the width/height of the widget to fill its parent
# we can select (X) for horizontally, (Y) for vertically, and (BOTH) for both directions 
# BUT we have to set (Expand) to (True)
button1.pack(fill=X, expand=True) 

# delete the (pack) geometry which will make the widget invisible again 
button1.pack_forget() 



The Grid geometry

It organizes widgets as a grid (table). The cell (0, 0) is located at the top left of the container.

# put the widget at the cell (0,1) in the grid, 
# and add a padding along both coordinates as (x=20, y=10)
button1.grid(row=0, column=1, padx=20, pady=10) 

# align the widget at the top-center of the cell (0, 1)
button1.grid(row=0, column=1, sticky="n") 
# n : north (top-center)
# s : south (bottom-center)
# e : east (right-center)
# w : west (left-center)
# ne : northeast (top-right-center)
# nw : northwest (top-left-center)
# se : southeast (bottom-right-center)
# se : southwest (bottom-left-center)
# nsew : center of the cell



The Place geometry

It organizes widgets by placing them in specific positions. The point (0, 0) is located at the top left of the container (parent).

# place the widget at the point (25, 80) -> (x, y)
button1.place(x=25, y=80) 

# relatively place the widget at x-percentage at (0.4) and y-percentage of (0.8) 
# the available scale here is from 0.0 to 0.9
button1.place(relx=0.4, rely=0.8)  


# edit column 3 to have 2 weights give it a minimum width of 75
walt.columnconfigure(3, weight=2, minsize=75) 
# edit row 5 to have a 4 weights and a minimum height of 50
walt.rowconfigure(5, weight=4, minsize=50) 
# edit more than one row at once
walt.rowconfigure( [ 2, 3, 7 ] , weight=4, minsize=5)

Comments