<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged tkinter</title>
<link>https://coderlegion.com/tag/tkinter</link>
<description>Powered by Question2Answer</description>
<item>
<title>Exploring More in Tkinter</title>
<link>https://coderlegion.com/253/exploring-more-in-tkinter</link>
<description>&lt;p&gt;In this article, we'll delve into some of the more intricate aspects of &lt;strong&gt;Tkinter&lt;/strong&gt;, exploring advanced techniques that will empower you to create even more powerful and polished GUI applications. Throughout our exploration, we'll uncover invaluable tools such as the &lt;strong&gt;&lt;code&gt;ttk&lt;/code&gt; module&lt;/strong&gt; for enhanced widget styling, the &lt;strong&gt;Canvas&lt;/strong&gt; widget for versatile graphics rendering, and the &lt;strong&gt;Grid&lt;/strong&gt; geometry manager for precise layout control.  From &lt;strong&gt;custom themes&lt;/strong&gt; to &lt;strong&gt;file handling strategies&lt;/strong&gt;, gear up to elevate your Tkinter expertise to the next level.&lt;/p&gt;
&lt;p&gt;If you are new to Tkinter, I highly recommend you to thoroughly review &lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/190/tkinter-library-in-python&quot;&gt;this article&lt;/a&gt; or the &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/tkinter.html&quot;&gt;official documentation&lt;/a&gt;. Familiarizing yourself with its contents will provide a solid foundation for understanding and effectively utilizing Tkinter.&lt;/p&gt;
&lt;p&gt;In the code snippets provided, add these lines in the beginning:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import tkinter as tk
from tkinter import ttk
window = tk.Tk()
window.geometry(&quot;457x335&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and this line at the end:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;window.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;custom-styles-and-themes&quot;&gt;Custom Styles and Themes&lt;/h2&gt;
&lt;p&gt;Tkinter enables customized visual presentation through custom styles and themes, using the &lt;code&gt;ttk&lt;/code&gt; module for personalized widget designs, ensuring consistency across platforms.&lt;/p&gt;
&lt;p&gt;To deepen our understanding, let's personalize our textbox, button, and label by customizing their appearance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import tkinter as tk
from tkinter import ttk

def submit_text():
    text = text_entry.get()
    text_label.config(text=text, font=(&quot;Times New Roman&quot;, 12, &quot;bold&quot;), foreground=&quot;green&quot;)     #customize label

window = tk.Tk()
window.geometry(&quot;457x335&quot;)
window.title(&quot;Custom Styles&quot;)

style = ttk.Style()     #to define custom styles
style.configure(&quot;Custom.TEntry&quot;, foreground=&quot;blue&quot;, fieldbackground=&quot;lightblue&quot;)     #customize textbox
style.configure(&quot;Custom.TButton&quot;, foreground=&quot;red&quot;, background=&quot;red&quot;)     #customize button

text_entry = ttk.Entry(window, width=30, style=&quot;Custom.TEntry&quot;)
text_entry.pack(padx=10, pady=10)
submit_button = ttk.Button(window, text=&quot;Submit&quot;, command=submit_text, style=&quot;Custom.TButton&quot;)     #sends entered text to the submit_text() function
submit_button.pack(padx=10, pady=5)
text_label = ttk.Label(window)
text_label.pack(padx=10, pady=10)
window.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=2820964779047794875&quot; alt=&quot;Tkinter_custom&quot;&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;submit_text&lt;/code&gt; function retrieves your text from the &lt;code&gt;text_entry&lt;/code&gt; textbox and updates the &lt;code&gt;text_label&lt;/code&gt; with it. The label's appearance is customized using Times New Roman font, size 12, bold, and green color. Custom styles (&lt;code&gt;Custom.TEntry&lt;/code&gt; for the textbox and &lt;code&gt;Custom.TButton&lt;/code&gt; for the button) are defined and configured using the &lt;code&gt;ttk.Style()&lt;/code&gt; method to set properties like &lt;code&gt;foreground&lt;/code&gt; and &lt;code&gt;background&lt;/code&gt; colors.&lt;/p&gt;
&lt;h2 id=&quot;integration-with-python-libraries&quot;&gt;Integration with Python Libraries&lt;/h2&gt;
&lt;p&gt; Tkinter can be integrated with other Python libraries and tools to enhance its functionality:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integration with Matplotlib&lt;/strong&gt;: You can make your Tkinter app more informative by adding interactive charts to display data trends or visualizations. By integrating Matplotlib, a popular Python library for creating charts and graphs, you can easily embed dynamic plots directly into your Tkinter windows.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integration with Scikit-learn&lt;/strong&gt;: You can combine Tkinter with Scikit-learn to develop GUI applications for machine learning tasks such as classification, regression, and clustering. This integration enables us to build interactive interfaces for training models, evaluating performance, and making predictions.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;div-blue&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Note:&lt;/span&gt;&lt;span class=&quot;alert-body&quot;&gt; In order to install sklearn library locally, run the command: `pip install scikit-learn`&lt;/span&gt; &lt;/div&gt;
&lt;div class=&quot;div-red&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Caution:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt;Ensure local compatibility by installing `matplotlib` and `matplotlib.backends.backend_tkagg` before running this code.&lt;/span&gt; &lt;/div&gt;
&lt;p&gt;Let's delve into the concept using an example of Linear Regression applied to predict outcomes for the Diabetes dataset:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import tkinter as tk
from tkinter import ttk     #for themed widgets
import matplotlib.pyplot as plt
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

diabetes = load_diabetes()     #Load the dataset
X_train, X_test, y_train, y_test = train_test_split(diabetes.data, diabetes.target, test_size=0.2, random_state=42)

window = tk.Tk()
window.geometry(&quot;650x500&quot;)
window.title(&quot;Diabetes Linear Regression&quot;)

def train_and_plot():
    model = LinearRegression()
    model.fit(X_train, y_train)     #train
    y_pred_train = model.predict(X_train)     #predict
    y_pred_test = model.predict(X_test)
    mse_train = mean_squared_error(y_train, y_pred_train)     #calculate mean squared error
    mse_test = mean_squared_error(y_test, y_pred_test)
    
    plt.figure(figsize=(8, 6))     #create the plot
    plt.scatter(y_test, y_pred_test, color='blue')
    plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], color='red', linestyle='--')
    plt.xlabel(&quot;Actual&quot;)
    plt.ylabel(&quot;Predicted&quot;)
    plt.title(&quot;Linear Regression Graph&quot;)
    plt.grid(True)
    plt.tight_layout()     #ensures the plot fits within the Tkinter window
    result_label.config(text=f&quot;Train MSE: {mse_train:.2f}\tTest MSE: {mse_test:.2f}&quot;)
    canvas = FigureCanvasTkAgg(plt.gcf(), master=window)     #converts the plot into a format that can be displayed in the Tkinter window
    canvas.draw()
    canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)     #adds the canvas widget to the Tkinter window.

train_button = ttk.Button(window, text=&quot;Train and Plot&quot;, command=train_and_plot)
train_button.pack(pady=10)
result_label = ttk.Label(window, text=&quot;&quot;)
result_label.pack()
window.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=10740781036814253574&quot; alt=&quot;Tkinter_interface&quot;&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;train_and_plot&lt;/code&gt; function trains a linear regression model on the dataset, predicts the target values, calculates the mean squared error for both training and testing sets, and then plots the predicted values against the actual values using matplotlib. It also displays the calculated mean squared errors on your GUI window.&lt;/p&gt;
&lt;h2 id=&quot;advanced-widgets&quot;&gt;Advanced Widgets&lt;/h2&gt;
&lt;p&gt;Tkinter provides a wide range of widgets beyond the basic ones like labels and buttons. You can explore and utilize widgets like treeview, notebook, progressbar, etc. to create sophisticated user interfaces.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;treeview&lt;/strong&gt; to display hierarchical data, like a file explorer.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; import tkinter as tk
 from tkinter import ttk     #for themed widgets
 window = tk.Tk()
 window.geometry(&quot;640x300&quot;)
 tree = ttk.Treeview(window)
 tree[&quot;columns&quot;] = (&quot;Fruits&quot;, &quot;Quantity&quot;)
 tree.heading(&quot;#0&quot;, text=&quot;Sr. No.&quot;)     #First column (index=0) will be Sr. No.
 tree.heading(&quot;Fruits&quot;, text=&quot;Fruits&quot;)
 tree.heading(&quot;Quantity&quot;, text=&quot;Quantity (kg)&quot;)
 tree.insert(&quot;&quot;, tk.END, text=&quot;1&quot;, values=(&quot;Apple&quot;, 30))
 tree.insert(&quot;&quot;, tk.END, text=&quot;2&quot;, values=(&quot;Orange&quot;, 25))
 tree.insert(&quot;&quot;, tk.END, text=&quot;3&quot;, values=(&quot;Mango&quot;, 29))
 tree.pack()
 window.mainloop()

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt; &lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=17024339317789079325&quot; alt=&quot;treeview&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Treeview widget &lt;code&gt;tree&lt;/code&gt; consists of two columns: &quot;Fruits&quot; and &quot;Quantity (kg)&quot;. The &lt;code&gt;heading&lt;/code&gt; method sets headings for each column, and the &lt;code&gt;insert&lt;/code&gt; method adds items to the Treeview. Each item is inserted with a unique identifier &quot;Sr. No.&quot; and its corresponding values for &quot;Fruits&quot; and &quot;Quantity&quot; are entered.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;notebook&lt;/strong&gt; to organize your app into different tabs, like in a web browser.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; import tkinter as tk
 from tkinter import ttk     #for themed widgets
 window = tk.Tk()
 window.geometry(&quot;457x335&quot;)
 notebook = ttk.Notebook(window)
 tab1 = ttk.Frame(notebook)
 tab2 = ttk.Frame(notebook)
 tab3 = ttk.Frame(notebook)
 label1 = tk.Label(tab1, text=&quot;This is Tab 1&quot;)     #for tab 1
 label1.pack()
 entry2 = tk.Entry(tab2)     #for tab 2
 entry2.pack()
 check_var = tk.BooleanVar()
 check_button3 = tk.Checkbutton(tab3, text=&quot;This is Tab 3&quot;, variable=check_var)     #for tab 3
 check_button3.pack()
 notebook.add(tab1, text=&quot;Tab 1&quot;)
 notebook.add(tab2, text=&quot;Tab 2&quot;)
 notebook.add(tab3, text=&quot;Tab 3&quot;)
 notebook.pack()
 window.mainloop()

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt; &lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=14879740221736993260&quot; alt=&quot;Tab1&quot;&gt;&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=14632322578103106639&quot; alt=&quot;Tab2&quot;&gt;&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=16524913512561924585&quot; alt=&quot;Tab3&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It creates a Notebook widget &lt;code&gt;notebook&lt;/code&gt;, which allows 3 tabs to be displayed, namely &lt;code&gt;Tab 1&lt;/code&gt;, &lt;code&gt;Tab 2&lt;/code&gt;, and &lt;code&gt;Tab 3&lt;/code&gt;, ceated using &lt;code&gt;ttk.Frame&lt;/code&gt;. &lt;code&gt;Tab 1&lt;/code&gt; contains a Label widget with the text &quot;This is Tab 1&quot;. &lt;code&gt;Tab 2&lt;/code&gt; contains an Entry widget for user input. &lt;code&gt;Tab 3&lt;/code&gt; contains a Checkbutton widget with the text &quot;This is Tab 3&quot;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;progressbar&lt;/strong&gt; to show how far along a task is, like when you're downloading a file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; import tkinter as tk
 from tkinter import ttk
 import time
    
 def start_task():
     progress_bar.start(10)     #start the progressbar (animation is updated every 10 milliseconds)
     window.after(3000, stop_task)     #simulate task completion after 3 seconds
    
 def stop_task():
     progress_bar.stop()      #stop the progressbar
    
 window = tk.Tk()
 window.geometry(&quot;457x335&quot;)
 progress_bar = ttk.Progressbar(window, orient=&quot;horizontal&quot;, length=200, mode=&quot;indeterminate&quot;)
 progress_bar.pack()
 start_button = tk.Button(window, text=&quot;Start Task&quot;, command=start_task)
 start_button.pack(pady=20)
 window.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt; &lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=17085322627996677804&quot; alt=&quot;Tkinter_progressbar&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When the &quot;Start Task&quot; button is clicked, it triggers the &lt;code&gt;start_task&lt;/code&gt; function, which starts the progress bar animation using the &lt;code&gt;start&lt;/code&gt; method. The &lt;code&gt;after&lt;/code&gt; method is used to schedule the &lt;code&gt;stop_task&lt;/code&gt; function to run after 3 seconds. The &lt;code&gt;stop_task&lt;/code&gt; function stops the progress bar animation using the &lt;code&gt;stop&lt;/code&gt; method.&lt;/p&gt;
&lt;h2 id=&quot;advanced-layout-management&quot;&gt;Advanced Layout Management&lt;/h2&gt;
&lt;p&gt;Advanced Layout Management can be used to make your Tkinter app look polished. Layout management helps you move widgets around and make your app look just the way you want using  &lt;code&gt;grid&lt;/code&gt;, &lt;code&gt;place&lt;/code&gt;, and &lt;code&gt;pack&lt;/code&gt; managers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Grid&lt;/strong&gt;&lt;br&gt;
You can place widgets in rows and columns, and they will organize neatly into place.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  import tkinter as tk
  window = tk.Tk()
  window.geometry(&quot;457x335&quot;)
  label1 = tk.Label(window, text=&quot;Subject&quot;)
  label2 = tk.Label(window, text=&quot;Marks&quot;)
  entry1 = tk.Entry(window)     #Widgets
  entry2 = tk.Entry(window)
  entry3 = tk.Entry(window)
  entry4 = tk.Entry(window)
  label1.grid(row=0, column=0)     #Layout
  label2.grid(row=0, column=1)
  entry1.grid(row=1, column=0)
  entry2.grid(row=1, column=1)
  entry3.grid(row=2, column=0)
  entry4.grid(row=2, column=1)
  window.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;  &lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=6534270145641510254&quot; alt=&quot;Tkinter_grid&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This code sets up 2 labels &lt;code&gt;Subject&lt;/code&gt; and &lt;code&gt;Marks&lt;/code&gt; and 4 entry widgets for data input. The layout is organized with &lt;code&gt;Subject&lt;/code&gt; in row 0, column 0, &lt;code&gt;Marks&lt;/code&gt; in row 0, column 1. Entry widgets &lt;code&gt;entry1&lt;/code&gt; and &lt;code&gt;entry2&lt;/code&gt; occupy row 1, columns 0 and 1 respectively, while &lt;code&gt;entry3&lt;/code&gt; and &lt;code&gt;entry4&lt;/code&gt; are in row 2, columns 0 and 1.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pack&lt;/strong&gt;&lt;br&gt;
You can stack widgets on top of each other or arrange them side by side, and Tkinter will figure out how to fit them all in.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  import tkinter as tk
  window = tk.Tk()
  window.geometry(&quot;457x335&quot;)
  button1 = tk.Button(window, text=&quot;Left&quot;)     #Widgets
  button2 = tk.Button(window, text=&quot;Top&quot;)
  button3 = tk.Button(window, text=&quot;Right&quot;)
  button4 = tk.Button(window, text=&quot;Bottom&quot;)
  button1.pack(side=tk.LEFT)     #Layout
  button2.pack(side=tk.TOP)
  button3.pack(side=tk.RIGHT)
  button4.pack(side=tk.BOTTOM)
  window.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;  &lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=15178167496495803908&quot; alt=&quot;Tkinter_pack&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The buttons &lt;code&gt;button1&lt;/code&gt;, &lt;code&gt;button2&lt;/code&gt;, &lt;code&gt;button3&lt;/code&gt; and &lt;code&gt;button4&lt;/code&gt; are positioned by providing the &lt;code&gt;side&lt;/code&gt; parameter with values &lt;code&gt;tk.LEFT&lt;/code&gt;, &lt;code&gt;tk.TOP&lt;/code&gt;, &lt;code&gt;tk.RIGHT&lt;/code&gt;, or &lt;code&gt;tk.BOTTOM&lt;/code&gt; respectively.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Place&lt;/strong&gt;&lt;br&gt;
You can specify exactly where you want each widget to go by giving it coordinates, like x and y coordinates on a graph.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  import tkinter as tk
  window = tk.Tk()
  window.geometry(&quot;457x335&quot;)
  label1 = tk.Label(window, text=&quot;x_50_y_50&quot;)     #Widgets
  label2 = tk.Label(window, text=&quot;x_200_y_200&quot;)
  label1.place(x=50, y=50)     #Layout
  label2.place(x=200, y=200)
  window.mainloop()

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;  &lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=11723976143771039796&quot; alt=&quot;Tkinter_place&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;place&lt;/code&gt; method is used to position label widgets. &lt;code&gt;label1&lt;/code&gt; is placed at coordinates (50, 50), and &lt;code&gt;label2&lt;/code&gt; is placed at coordinates (200, 200).&lt;/p&gt;
&lt;h2 id=&quot;file-handling&quot;&gt;File Handling&lt;/h2&gt;
&lt;p&gt;Tkinter facilitates file handling through the &lt;code&gt;filedialog&lt;/code&gt; tool, enabling users to interactively select files on their computer. With this feature, your application can support tasks like creating, opening, saving, and editing various file types such as documents, images, or spreadsheets.&lt;/p&gt;
&lt;p&gt;Let's understand this using an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import tkinter as tk
from tkinter import filedialog

def open_file():
    file_path = filedialog.askopenfilename()     #opens a dialog window to select an existing file or create a new one
    if not file_path:
        return
    with open(file_path, 'a+') as file:     #'a+' to append the text to the file
        file.write(&quot;January\n&quot;)
        file.write(&quot;February\n&quot;)
        file.write(&quot;March\n&quot;)
        file.write(&quot;April\n&quot;)
        file.write(&quot;May\n&quot;)
    status_label.config(text=f&quot;File '{file_path}' has been written and closed.&quot;)

window = tk.Tk()
window.geometry(&quot;457x335&quot;)
window.title(&quot;File Writer&quot;)
open_button = tk.Button(window, text=&quot;Open a File&quot;, command=open_file)
open_button.pack(pady=20)
status_label = tk.Label(window, text=&quot;&quot;)
status_label.pack()
root.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=16945057073417130965&quot; alt=&quot;file&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=2325960918843338371&quot; alt=&quot;file_open_1&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=15519562952456146282&quot; alt=&quot;file_open_2&quot;&gt;&lt;/p&gt;
&lt;p&gt;When clicked, the button &quot;Open a File&quot; triggers the &lt;code&gt;open_file&lt;/code&gt; function, which opens a dialog window allowing you to select an existing file or create a new one. If a file is selected, the code appends the strings &quot;January&quot;, &quot;February&quot;...&quot;May&quot; to the file and the file is closed. The &lt;code&gt;status_label&lt;/code&gt; is then updated to display a message confirming the file write operation.&lt;/p&gt;
&lt;div class=&quot;div-blue&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Note:&lt;/span&gt;  &lt;span class=&quot;alert-body&quot;&gt; The file will automatically be closed when the `with` block is exited. However, you may explicitly close the file by calling `file.close()`.&lt;/span&gt; &lt;/div&gt;
&lt;h2 id=&quot;modal-and-modeless-dialogs&quot;&gt;Modal and Modeless Dialogs&lt;/h2&gt;
&lt;p&gt;Tkinter offers both modal and modeless dialogs, ideal for user input, confirmation messages, or notifications. The &lt;code&gt;tkinter.messagebox&lt;/code&gt; module provides standard message boxes, while custom dialog windows can be created using &lt;code&gt;Toplevel&lt;/code&gt; widgets.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modal dialogs&lt;/strong&gt; are windows that require the user to interact with them before returning to the main application window. They typically block interaction with other windows in the application until they are closed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  import tkinter as tk
  from tkinter import messagebox

  def show_modal_dialog():
      messagebox.showinfo(&quot;Modal Dialog&quot;, &quot;Pay attention to this dialog box!&quot;)     #does not let you proceed until you click the &quot;OK&quot; button

  window = tk.Tk()
  window.geometry(&quot;457x335&quot;)
  window.title(&quot;Modal Dialog Example&quot;)
  modal_button = tk.Button(window, text=&quot;Click me&quot;, command=show_modal_dialog)
  modal_button.pack(padx=20, pady=10)
  window.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;  &lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=5781727160550960337&quot; alt=&quot;Tkinter_modal_dialog&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modeless dialogs&lt;/strong&gt; are windows that allow the user to interact with both the dialog and the main application window simultaneously. They do not block interaction with other windows in the application, allowing the user to switch between them freely.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  import tkinter as tk

  def show_modeless_dialog():
      modeless_dialog = tk.Toplevel(window)     #allows you to interact with other open windows
      modeless_dialog.title(&quot;Modeless Dialog&quot;)
      modeless_dialog.geometry(&quot;250x100&quot;)
      label = tk.Label(modeless_dialog, text=&quot;Have a nice day!&quot;)
      label.pack(padx=20, pady=10)

  window = tk.Tk()
  window.geometry(&quot;457x335&quot;)
  window.title(&quot;Modeless Dialog Example&quot;)
  modeless_button = tk.Button(window, text=&quot;Click me&quot;, command=show_modeless_dialog)
  modeless_button.pack(padx=20, pady=10)
  window.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;  &lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=1548469847260034179&quot; alt=&quot;Tkinter_modaless_dialog&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When clicked, the button &quot;Click me&quot; triggers the &lt;code&gt;show_modeless_dialog&lt;/code&gt; function, which creates a modeless dialog box using the &lt;code&gt;Toplevel&lt;/code&gt; widget. It will not hinder your interaction with the other windows.&lt;/p&gt;
&lt;div class=&quot;div-green&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Tip:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt; Using a class for modeless dialogs can organize and encapsulate dialog functionality, particularly for more intricate dialogs with multiple components and interactions.&lt;/span&gt; &lt;/div&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Tkinter&lt;/strong&gt; is a versatile Python &lt;strong&gt;GUI&lt;/strong&gt; framework that enhances user interaction and functionality. With features like &lt;strong&gt;custom themes&lt;/strong&gt;, &lt;strong&gt;threading&lt;/strong&gt;, &lt;strong&gt;file handling&lt;/strong&gt;, &lt;strong&gt;dialogs&lt;/strong&gt;, &lt;strong&gt;layout management&lt;/strong&gt;, &lt;strong&gt;advanced widgets&lt;/strong&gt;, and integration with libraries like Matplotlib and scikit-learn, Tkinter empowers developers to create dynamic desktop applications. By leveraging these capabilities, developers can craft unique GUIs that elevate user experience, making Tkinter a top choice for Python GUI projects.&lt;/p&gt;
</description>
<category>Project Dev</category>
<guid isPermaLink="true">https://coderlegion.com/253/exploring-more-in-tkinter</guid>
<pubDate>Tue, 23 Apr 2024 21:35:28 +0000</pubDate>
</item>
<item>
<title>Building a Calculator using tkinter</title>
<link>https://coderlegion.com/210/building-a-calculator-using-tkinter</link>
<description>&lt;p&gt;When working on a basic calculator with &lt;strong&gt;Tkinter&lt;/strong&gt;, a widely-used GUI toolkit for &lt;strong&gt;Python&lt;/strong&gt;, Tkinter streamlines the incorporation of user-friendly elements such as buttons, entries, grids, and custom styles that are necessary for crafting graphical user interfaces, making it particularly well-suited for applications. Its simplicity and efficiency in managing user interactions make it an ideal choice for projects of this nature.&lt;/p&gt;
&lt;h2 id=&quot;creating-the-calculator&quot;&gt;Creating the Calculator&lt;/h2&gt;
&lt;p&gt;Now let us actually dive into the process of building the calculator, one step at a time. All the required steps are given below; follow them one by one, and you will be able to develop an efficient and interactive calculator.&lt;/p&gt;
&lt;h3 id=&quot;step-1-setting-up-environment&quot;&gt;Step 1: Setting Up Environment&lt;/h3&gt;
&lt;p&gt;Before we start building our calculator, ensure that you have Python installed on your system. To do so, the following section gives a short guide on the steps to be followed for different platforms.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For Windows:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download and install Python from the &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.python.org/downloads/&quot;&gt;official website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify by running the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; python --version
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;For Linux:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open terminal and copy and paste the code&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; sudo apt-get update
 sudo apt-get install python3
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once installed verify by running the following command&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; python --version
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;For MacOs:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download and install Python from the &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.python.org/downloads/macos/&quot;&gt;official website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;For reference &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/using/mac.html&quot;&gt;Steps to install python on MacOs&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, we need to install Tkinter, which is included with Python by default. So, there's no need to install it separately&lt;/p&gt;
&lt;h3 id=&quot;step-2-importing-libraries&quot;&gt;Step 2: Importing Libraries&lt;/h3&gt;
&lt;p&gt;In Python, the tkinter module is used for creating GUI applications. &lt;br&gt;
Now let's import these required libraries along with other required modules:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import tkinter as tk
from tkinter import messagebox
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;tkinter&lt;/strong&gt;: This module provides classes and functions for creating GUI applications.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;messagebox&lt;/strong&gt;: This submodule allows us to display message boxes for showing information or prompting the user for confirmation.&lt;/p&gt;
&lt;h3 id=&quot;step-3-creating-the-calculator-class&quot;&gt;Step 3: Creating the Calculator Class&lt;/h3&gt;
&lt;p&gt;Create a class called  &lt;code&gt;class Calculator&lt;/code&gt; that will represent our calculator application:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Calculator:
    def __init__(self, master):
        self.master = master
        self.master.title(&quot;Simple Calculator&quot;)
        self.master.geometry(&quot;300x400&quot;)
        self.master.resizable(False, False)
        self.create_widgets()

    def create_widgets(self):
        # Create entry widget for displaying input and results
        self.entry = tk.Entry(self.master, width=20, font=('Arial', 14), bd=5, justify=&quot;right&quot;)
        self.entry.grid(row=0, column=0, columnspan=4, padx=10, pady=10)

        # Define buttons
        buttons = [
            ('7', 1, 0), ('8', 1, 1), ('9', 1, 2), ('/', 1, 3),
            ('4', 2, 0), ('5', 2, 1), ('6', 2, 2), ('*', 2, 3),
            ('1', 3, 0), ('2', 3, 1), ('3', 3, 2), ('-', 3, 3),
            ('0', 4, 0), ('.', 4, 1), ('=', 4, 2), ('+', 4, 3)
        ]

        # Create buttons using a loop
        for (text, row, col) in buttons:
            button = tk.Button(self.master, text=text, width=5, height=2, 
            font=('Arial', 14), command=lambda t=text: self.on_button_click(t))
            button.grid(row=row, column=col, padx=5, pady=5)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Initialization&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;init&lt;/code&gt; method in the Calculator class sets up the basic features of the calculator when it's first created. It's like laying out the blueprint for how the calculator will look and work. The &lt;code&gt;master&lt;/code&gt; part helps position the calculator in the right place on the screen. &lt;code&gt;self.master.title(&quot;Simple Calculator&quot;)&lt;/code&gt; gives the calculator window a name, like &quot;Simple Calculator&quot;. The &lt;code&gt;self.master.geometry(&quot;300x400&quot;)&lt;/code&gt; part determines how big the calculator window will be, making sure it's neither too small nor too big. The line&lt;code&gt;self.master.resizable(False, False)&lt;/code&gt; prevents users from changing the size of the calculator window, keeping it neat and tidy. Finally, &lt;code&gt;self.create_widgets()&lt;/code&gt; starts the process of actually creating all the buttons and numbers you see on the calculator screen. It's like setting up the stage before the show begins. So, with all these steps, the calculator is ready to go when you open it up!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Widget Creation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;create_widgets&lt;/code&gt; method orchestrates the construction of the calculator's user interface, beginning with the establishment of an entry widget named &lt;code&gt;self.entry&lt;/code&gt; for displaying input and results, meticulously configured with specific attributes such as width, font size, border width, and text alignment. Positioned within the window using the grid method, this entry widget ensures clarity and organization of numerical data. Subsequently, utilizing a list named &lt;code&gt;buttons&lt;/code&gt; containing tuples of button details, the method dynamically generates button widgets for each entry within the list. These buttons, equipped with attributes such as text labels and dimensions, are seamlessly integrated into the window using the grid method, with each button assigned a command to execute the &lt;code&gt;on_button_click&lt;/code&gt; method upon interaction, passing the corresponding button text as an argument. Through meticulous placement and configuration, the &lt;code&gt;create_widgets&lt;/code&gt; method establishes a coherent and functional user interface, essential for intuitive interaction and efficient calculation.&lt;/p&gt;
&lt;h3 id=&quot;step-4-implementing-button-click-functionality&quot;&gt;Step 4: Implementing Button Click Functionality&lt;/h3&gt;
&lt;p&gt;Next, we define the &lt;code&gt;on_button_click()&lt;/code&gt; method to handle button clicks:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def on_button_click(self, text):
     if text == '=':
          try:
              result = eval(self.entry.get())
              self.entry.delete(0, tk.END)
              self.entry.insert(tk.END, str(result))
          except Exception as e:
              messagebox.showerror(&quot;Error&quot;, &quot;Invalid Input&quot;)

          elif text == 'C':
              self.entry.delete(0, tk.END)

          else:
              self.entry.insert(tk.END, text)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this block of code, several conditional statements and actions are executed based on the text of the clicked button within the calculator interface. First, there's a check to see if the button text is equal to '=' (the equal sign). If so, the mathematical expression entered in the entry widget (self.entry) is evaluated using the &lt;code&gt;eval()&lt;/code&gt; function, and the result is stored in the &lt;code&gt;result&lt;/code&gt; variable. The contents of the entry widget are then cleared using &lt;code&gt;self.entry.delete(0, tk.END)&lt;/code&gt;, and the calculated result is inserted into the entry widget using &lt;code&gt;self.entry.insert(tk.END, str(result))&lt;/code&gt;. In case an exception occurs during evaluation, it's caught using a try-except block, and an error message box is displayed using &lt;code&gt;messagebox.showerror(&quot;Error&quot;, &quot;Invalid Input&quot;)&lt;/code&gt;. Lastly, the text of the clicked button is inserted into the entry widget at the end (tk.END) using &lt;code&gt;self.entry.insert(tk.END, text)&lt;/code&gt;, allowing users to append their input string. These actions ensure proper functionality and user feedback within the calculator interface, facilitating smooth interaction and accurate computation.&lt;/p&gt;
&lt;h3 id=&quot;step-5-driver-function&quot;&gt;Step 5: Driver Function&lt;/h3&gt;
&lt;p&gt;Lastly, we need to create an instance of the Calculator class and run the &lt;code&gt;main&lt;/code&gt; event loop:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; if __name__ == &quot;__main__&quot;:
     root = tk.Tk()
     app = Calculator(root)
     root.mainloop()   
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The line &lt;code&gt; if __name__ == &quot;__main__&quot;&lt;/code&gt; serves as a conditional statement that ensures that the subsequent code block is executed only if the Python script is directly run by the interpreter, rather than being imported as a module into another script. Following this condition, &lt;code&gt;root = tk.Tk()&lt;/code&gt; initializes a new instance of the Tkinter Tk class, establishing the main window or root window for the graphical user interface (GUI) application. This window acts as a container for all other GUI elements to be displayed. Subsequently, &lt;code&gt;app = Calculator(root)&lt;/code&gt; creates an instance of the Calculator class, utilizing the root window as an argument, thereby initializing the calculator application within this main window. Lastly, &lt;code&gt;root.mainloop()&lt;/code&gt; initiates the Tkinter event loop, a critical component that continuously listens for user interactions, such as button clicks and window resizing, effectively maintaining the responsiveness of the GUI. This function call essentially blocks further script execution until the main window is closed by the user, ensuring the seamless functioning of the GUI application.&lt;/p&gt;
&lt;h3 id=&quot;step-6-outcome-of-implementation&quot;&gt;Step 6: Outcome of Implementation&lt;/h3&gt;
&lt;p&gt;  &lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=7603950783710353489&quot; alt=&quot;Outcome&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;code-snippet&quot;&gt;Code snippet&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;import tkinter as tk
from tkinter import messagebox

class Calculator:
    def __init__(self, master):
        self.master = master
        self.master.title(&quot;Simple Calculator&quot;)
        self.master.geometry(&quot;300x400&quot;)
        self.master.resizable(False, False)
        self.create_widgets()

    # creating the widgets
    
    def create_widgets(self):
        # Create entry widget for displaying input and results
        self.entry = tk.Entry(
            self.master, width=20, font=(&quot;Arial&quot;, 14), bd=5, justify=&quot;right&quot;
        )
        self.entry.grid(row=0, column=0, columnspan=4, padx=10, pady=10)

        # Define buttons
        buttons = [
            (&quot;7&quot;, 1, 0),
            (&quot;8&quot;, 1, 1),
            (&quot;9&quot;, 1, 2),
            (&quot;/&quot;, 1, 3),
            (&quot;4&quot;, 2, 0),
            (&quot;5&quot;, 2, 1),
            (&quot;6&quot;, 2, 2),
            (&quot;*&quot;, 2, 3),
            (&quot;1&quot;, 3, 0),
            (&quot;2&quot;, 3, 1),
            (&quot;3&quot;, 3, 2),
            (&quot;-&quot;, 3, 3),
            (&quot;0&quot;, 4, 0),
            (&quot;.&quot;, 4, 1),
            (&quot;=&quot;, 4, 2),
            (&quot;+&quot;, 4, 3),
        ]

        # Create buttons using a loop
        for text, row, col in buttons:
            button = tk.Button(
                self.master,
                text=text,
                width=5,
                height=2,
                font=(&quot;Arial&quot;, 14),
                command=lambda t=text: self.on_button_click(t),
            )
            button.grid(row=row, column=col, padx=5, pady=5)

    # funtion creation for on click feature
    def on_button_click(self, text):
        if text == &quot;=&quot;:
            try:
                result = eval(self.entry.get())
                self.entry.delete(0, tk.END)
                self.entry.insert(tk.END, str(result))
            except Exception as e:
                messagebox.showerror(&quot;Error&quot;, &quot;Invalid Input&quot;)

        elif text == &quot;C&quot;:
            self.entry.delete(0, tk.END)

        else:
            self.entry.insert(tk.END, text)

    # main funtion is defined                
    if __name__ == &quot;__main__&quot;:
        root = tk.Tk()
        app = Calculator(root)
        root.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;understanding-code-functionality&quot;&gt;Understanding Code Functionality&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When the calculator starts, it creates a window with an entry widget. This widget is where you can input numbers and view the results.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The calculator has buttons for digits from 0 to 9, the decimal point '.', and arithmetic operations like addition '+', subtraction '-', multiplication '*', and division '/'. These buttons are arranged in a grid layout.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;div-green&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Tip:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt;Implement input validation to avoid potential security vulnerabilities or crashes. &lt;/span&gt; &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When a button is clicked, it triggers the &lt;code&gt;on_button_click&lt;/code&gt; function. If the button is an arithmetic operation or a digit, it adds that value to the entry widget. If the button is '=' (equal sign), it evaluates the expression in the entry widget and displays the result. If it's 'C' (clear), it clears the entry widget.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When '=' is pressed, it tries to evaluate the expression entered in the entry widget using Python's &lt;code&gt;eval()&lt;/code&gt; function. If the expression is valid, it computes the result and displays it in the entry widget. If there's an error, such as invalid input or division by zero, it shows an error message.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;div-red&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Warning:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt;Avoid using the eval() function with untrusted input to prevent code injection vulnerabilities.&lt;/span&gt;  &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The program keeps running in a loop, waiting for user interactions, until the window is closed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Users can input numbers and perform arithmetic operations by clicking the respective buttons. They can clear the input by clicking 'C' and get the result by clicking '='.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;calculator-functionality-flowchart&quot;&gt;Calculator Functionality Flowchart&lt;/h2&gt;
&lt;p&gt;Following is an illustration of the functionality of a simple calculator program through a clear and logical flowchart.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=14107652295060674798&quot; alt=&quot;Flowchart&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;testing-result&quot;&gt;Testing Result&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=250390329310505356&quot; alt=&quot;Testing 1&quot;&gt;        &lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=4300637587976812647&quot; alt=&quot;Testing 2&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;possible-errors-that-might-occur&quot;&gt;Possible Errors that might occur&lt;/h2&gt;
&lt;p&gt;In building a calculator using Tkinter, potential errors include syntax mistakes, input validation issues, and challenges with complex operations. Effective debugging is crucial for ensuring the calculator functions reliably. Have a look at some of the problems along with their solutions that are listed below.&lt;/p&gt;
&lt;h3 id=&quot;division-by-zero-error-&quot;&gt;Division by zero error:&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: If the user divides by zero, Python will raise a ZeroDivisionError.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=5214973538443658959&quot; alt=&quot;Invalid Input&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Handle division by zero within the try-except block.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try:
    result = eval(self.entry.get())
    if result == float('inf'):
         messagebox.showerror(&quot;Error&quot;, &quot;Division by zero&quot;)
    else:
        self.entry.delete(0, tk.END)
        self.entry.insert(tk.END, str(result))
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;syntax-error-in-evaluation-&quot;&gt;Syntax error in evaluation:&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: If the user enters an invalid expression that can't be evaluated, it will raise a SyntaxError.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=11542053887820982095&quot; alt=&quot;Invalid Input 2&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Catch SyntaxError and display an appropriate error message.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;except SyntaxError:
messagebox.showerror(&quot;Error&quot;, &quot;Invalid Expression&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;nameerror-due-to-undefined-variable-&quot;&gt;NameError due to undefined variable:&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: The code checks for the '=' and 'C' buttons, but they're not defined in the button list.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Add the '=' and 'C' buttons to the list with their respective positions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;buttons = [
   ...
   ('=', 4, 2), ('C', 4, 0)
]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;missing-import-statement-&quot;&gt;Missing import statement:&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: The code uses messagebox without importing it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Import messagebox from tkinter.&lt;/p&gt;
&lt;p&gt;from tkinter import messagebox&lt;/p&gt;
&lt;h3 id=&quot;unsupported-operations-&quot;&gt;Unsupported operations:&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: The calculator allows arbitrary evaluation of expressions &lt;code&gt;using eval()&lt;/code&gt;, which can lead to unintended consequences.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Restrict the input to a certain format or implement a safer method for evaluation, such as parsing the expression manually.&lt;br&gt;
Here's a safer approach to evaluate expressions using &lt;code&gt;ast.literal_eval()&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import ast
def evaluate_expression(self, expression):
    try:
        return ast.literal_eval(expression)
    except (SyntaxError, ValueError):
        raise ValueError(&quot;Invalid expression&quot;)
  
def on_button_click(self, text):
    if text == '=':
        try:
            result = self.evaluate_expression(self.entry.get())
            self.entry.delete(0, tk.END)
            self.entry.insert(tk.END, str(result))
        except ValueError as e:
            messagebox.showerror(&quot;Error&quot;, str(e))
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion-&quot;&gt;Conclusion:&lt;/h2&gt;
&lt;p&gt;In conclusion, developing a simple calculator using &lt;strong&gt;Tkinter&lt;/strong&gt; in Python, offers a practical introduction to GUI application development. Tkinter's intuitive design, coupled with its &lt;strong&gt;cross-platform compatibility&lt;/strong&gt;, empowers developers to create interactive interfaces effortlessly. By leveraging Tkinter's event-driven model, we constructed a calculator with &lt;strong&gt;basic arithmetic operations&lt;/strong&gt;, &lt;strong&gt;error handling&lt;/strong&gt;, and &lt;strong&gt;clear functionality&lt;/strong&gt;. Utilizing widgets like &lt;strong&gt;Entry&lt;/strong&gt; and &lt;strong&gt;Button&lt;/strong&gt;, we orchestrated a user-friendly interface, enhancing accessibility and the user experience.&lt;/p&gt;
&lt;p&gt;Throughout the process, we capitalized on &lt;strong&gt;object-oriented programming&lt;/strong&gt; principles, encapsulating functionality within the Calculator class. This modular approach facilitates code organization and maintenance, promoting scalability and extensibility. Moreover, the integration of error handling mechanisms, such as &lt;strong&gt;try-except blocks&lt;/strong&gt; and &lt;strong&gt;message boxes&lt;/strong&gt;, underscores the importance of robustness in software design. These measures ensure graceful handling of unexpected inputs, enhancing the calculator's reliability and user confidence.&lt;/p&gt;
&lt;p&gt;By adhering to best practices and leveraging Tkinter's capabilities, we've crafted a functional calculator application that demonstrates the synergy between Python's versatility and Tkinter's simplicity. This endeavor serves as a springboard for aspiring developers to delve deeper into GUI programming and explore the myriad possibilities of Python's ecosystem.&lt;/p&gt;
</description>
<category>Project Dev</category>
<guid isPermaLink="true">https://coderlegion.com/210/building-a-calculator-using-tkinter</guid>
<pubDate>Tue, 02 Apr 2024 20:46:16 +0000</pubDate>
</item>
<item>
<title>Convert Tkinter Python App to .Exe File [pyinstaller] Step by Step Guide</title>
<link>https://coderlegion.com/209/convert-tkinter-python-app-to-exe-file-pyinstaller-step-by-step-guide</link>
<description>&lt;p&gt;In this article, you will learn how to distribute a &lt;strong&gt;Tkinter&lt;/strong&gt; project an as &lt;strong&gt;.exe&lt;/strong&gt; setup file using &lt;strong&gt;PyInstaller&lt;/strong&gt;. This converts Python scripts into &lt;strong&gt;standalone executables&lt;/strong&gt; and makes it easy for people to install and use your applications. Users don't need to worry about installing Python or managing dependencies. This way, your programs can be easily moved between different computers and run securely. Plus, it gives your projects a more polished and professional look.&lt;/p&gt;
&lt;h2 id=&quot;environment-setup&quot;&gt;Environment Setup&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Python&lt;/strong&gt;: Ensure that Python is installed on your system, which includes Tkinter by default. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;For Windows&lt;/strong&gt;: Download and install Python from the &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.python.org/downloads&quot;&gt;official website&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For Ubuntu&lt;/strong&gt;: You can download Python using the terminal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  sudo apt update
  sudo apt install python3
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For MacOS&lt;/strong&gt;: You can download Python using Homebrew:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  brew install python3
  Confirm the installation by typing `python3 --version` in the terminal.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PyInstaller&lt;/strong&gt;: It is necessary for converting Python scripts into executable files. Launch your terminal or command prompt and execute the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  pip install pyinstaller
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;IDE or Text Editor&lt;/strong&gt;: Choose a preferred text editor or IDE like Visual Studio Code for coding.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tkinter&lt;/strong&gt;: Basic understanding of Tkinter, including widgets and event handling, is beneficial. Refer to the &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/tkinter.html&quot;&gt;Tkinter documentation&lt;/a&gt; or &lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/190/introduction-to-tkinter-library-in-python&quot;&gt;this article&lt;/a&gt; for learning.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;div-blue&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Note:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt; This project expects familiarity with basic Python concepts.&lt;/span&gt; &lt;/div&gt;
&lt;h2 id=&quot;developing-a-tkinter-project&quot;&gt;Developing a Tkinter Project&lt;/h2&gt;
&lt;p&gt;Do check out &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/tk.html&quot;&gt;the documentation&lt;/a&gt; to learn more about GUI using Tkinter.&lt;/p&gt;
&lt;p&gt;We will create a simple calculator application using Tkinter in Python. It allows you to input two numbers and select an operation (addition, subtraction, multiplication, or division) using radio buttons. Upon clicking the &quot;Calculate&quot; button, the program performs the selected operation on the input numbers and displays the result in a modeless dialog box.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import tkinter as tk
from tkinter import messagebox

def  calculate():
num1 = float(entry1.get())
num2 = float(entry2.get())
if operation.get() == 1:     # Add
result = num1 + num2
elif operation.get() == 2:     # Subtract
result = num1 - num2
elif operation.get() == 3:     # Multiply
result = num1 * num2
elif operation.get() == 4:     # Divide
if num2 == 0:
messagebox.showerror(&quot;Error&quot;, &quot;Cannot divide by zero&quot;)
return
result = num1 / num2
result_window = tk.Toplevel(window)     # Modeless dialog box
result_window.geometry(&quot;200x100&quot;)
result_window.title(&quot;Result&quot;)
result_label = tk.Label(result_window, text=f&quot;The result is: {result}&quot;)     # Label widget
result_label.pack()

window = tk.Tk()     # Main window
window.geometry(&quot;457x335&quot;)
window.title(&quot;Calculator&quot;)

frame_numbers = tk.Frame(window)     # Frame
frame_numbers.pack()
label1 = tk.Label(frame_numbers, text=&quot;Number 1:&quot;)     # Labels and Entry widgets
label1.grid(row=0, column=0)
entry1 = tk.Entry(frame_numbers)
entry1.grid(row=0, column=1)
label2 = tk.Label(frame_numbers, text=&quot;Number 2:&quot;)
label2.grid(row=1, column=0)
entry2 = tk.Entry(frame_numbers)
entry2.grid(row=1, column=1)
frame_operations = tk.Frame(window)     # Frame
frame_operations.pack()
operation = tk.IntVar()     # Radiobuttons
addition = tk.Radiobutton(frame_operations, text=&quot;Addition&quot;, variable=operation, value=1)
addition.grid(row=0, column=0, sticky=&quot;w&quot;)
subtraction = tk.Radiobutton(frame_operations, text=&quot;Subtraction&quot;, variable=operation, value=2)
subtraction.grid(row=1, column=0, sticky=&quot;w&quot;)
multiplication = tk.Radiobutton(frame_operations, text=&quot;Multiplication&quot;, variable=operation, value=3)
multiplication.grid(row=2, column=0, sticky=&quot;w&quot;)
division = tk.Radiobutton(frame_operations, text=&quot;Division&quot;, variable=operation, value=4)
division.grid(row=3, column=0, sticky=&quot;w&quot;)
error_label = tk.Label(window, fg=&quot;red&quot;)     # Error label
error_label.pack()
calculate_button = tk.Button(window, text=&quot;Calculate&quot;, command=calculate)     # Button
calculate_button.pack()
window.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Firstly, import the Tkinter module and create a main window using &lt;code&gt;tk.Tk()&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Two frames, &lt;code&gt;frame_numbers&lt;/code&gt; and &lt;code&gt;frame_operations&lt;/code&gt;, are created to organize the layout of the widgets.&lt;/li&gt;
&lt;li&gt;Labels and Entry widgets are placed inside &lt;code&gt;frame_numbers&lt;/code&gt; to allow users to input two numbers.&lt;/li&gt;
&lt;li&gt;Radiobuttons, &lt;code&gt;addition&lt;/code&gt;, &lt;code&gt;subtraction&lt;/code&gt;, &lt;code&gt;multiplication&lt;/code&gt;, and &lt;code&gt;division&lt;/code&gt;, are placed inside &lt;code&gt;frame_operations&lt;/code&gt; to select the desired operation.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;messagebox&lt;/code&gt; is created to display error messages, such as division by zero.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;calculate()&lt;/code&gt; function is defined to perform the calculation based on user input. It retrieves the input numbers and selected operation, calculates the result, and creates a modeless dialog box &lt;code&gt;result_window&lt;/code&gt; using &lt;code&gt;tk.Toplevel()&lt;/code&gt; to display the result.&lt;/li&gt;
&lt;li&gt;Finally, the main event loop &lt;code&gt;window.mainloop()&lt;/code&gt; is started to run the application.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=11940241863597782013&quot; alt=&quot;pyinstl_calculator&quot;&gt;&lt;/p&gt;
&lt;div class=&quot;div-green&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Tip:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt; It is best to encapsulate functions and shared variables within a class.&lt;/span&gt; &lt;/div&gt;
&lt;h2 id=&quot;installing-pyinstaller&quot;&gt;Installing PyInstaller&lt;/h2&gt;
&lt;p&gt;To install PyInstaller using pip, follow these steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open your terminal or command prompt on your computer.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type the following command and press Enter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  pip install pyinstaller
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once the installation is complete, you can verify that PyInstaller has been installed correctly by running:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  pyinstaller --version
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt; This command will display the version of PyInstaller installed on your system.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here's how PyInstaller converts python scripts to executable files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PyInstaller analyzes Python scripts and their dependencies.&lt;/li&gt;
&lt;li&gt;It bundles all dependencies, including the Python interpreter, into a single package.&lt;/li&gt;
&lt;li&gt;It creates standalone executables that can run independently on compatible systems.&lt;/li&gt;
&lt;li&gt;The tool optimizes and compresses the executable for efficient distribution.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;div-blue&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Note:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt; PyInstaller is cross-platform, supporting Windows, macOS, and Linux.&lt;/span&gt; &lt;/div&gt;
&lt;h2 id=&quot;converting-tkinter-project-to-exe-file&quot;&gt;Converting Tkinter Project to .exe File&lt;/h2&gt;
&lt;p&gt;Let's convert our calculator script to a .exe file.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open a command prompt or terminal window.&lt;/li&gt;
&lt;li&gt;Navigate to the directory containing your Python script.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  pyinstaller --onefile --windowed calculator.py
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;--onefile&lt;/code&gt; bundles everything into a single executable and &lt;code&gt;--windowed&lt;/code&gt; creates a GUI application without a console window.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PyInstaller will analyze your script and create a &lt;code&gt;dist&lt;/code&gt; directory in the same location, containing the converted .exe file (calculator.exe).&lt;/li&gt;
&lt;li&gt;Once the process is complete, you can find the &lt;code&gt;calculator.exe&lt;/code&gt; file in the &lt;code&gt;dist&lt;/code&gt; directory.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=10409504070909312298&quot; alt=&quot;pyinstl_run&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=16231717955459463347&quot; alt=&quot;pyinstl_dist&quot;&gt;&lt;/p&gt;
&lt;div class=&quot;div-red&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Caution:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt; Ensure that the Tkinter module has been installed.&lt;/span&gt; &lt;/div&gt;
&lt;p&gt;Possible Errors that you may encounter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ModuleNotFoundError&lt;/strong&gt;: To resolve PyInstaller's inability to locate some imported modules or dependencies, ensure all required modules are installed and accessible. You can install missing modules using pip.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Large Executable Size&lt;/strong&gt;: Optimize PyInstaller options to reduce .exe size. Use &lt;code&gt;--onefile&lt;/code&gt; for a single executable or &lt;code&gt;--exclude-module&lt;/code&gt; to exclude modules.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PermissionError&lt;/strong&gt;: Ensure you have write permissions for the output directory to avoid permission errors during PyInstaller execution.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Anti-virus False Positives&lt;/strong&gt;: Anti-virus programs may flag the .exe file as suspicious due to file bundling. To fix, whitelist the .exe or sign it with a digital signature.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;customizing-the-exe-setup-file&quot;&gt;Customizing the .exe Setup File&lt;/h2&gt;
&lt;p&gt;To customize the .exe file generated by PyInstaller, you can add a custom icon, metadata using specific options, window size and title of the .exe file.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom Icon&lt;/strong&gt;: Utilize the &lt;code&gt;--icon&lt;/code&gt; option followed by the path to your icon file (.ico). This sets the icon for the executable.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  pyinstaller --onefile --icon=calculator_icon.ico calculator.py
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Metadata&lt;/strong&gt;: Craft a version file (.rc or .ini) containing metadata like file description, product name, and version information. Then, use the &lt;code&gt;--version-file&lt;/code&gt; option to specify the path to this file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  pyinstaller --onefile --version-file=calculator_version.rc calculator.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt; Example of calculator_version.rc:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  1 VERSIONINFO
  FILEVERSION 1,0,0,0
  PRODUCTVERSION 1,0,0,0
  FILEDESCRIPTION &quot;Calculator Application&quot;
  PRODUCTNAME &quot;Calculator&quot;
  ICON &quot;calculator_icon.ico&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Window Size&lt;/strong&gt;: Use &lt;code&gt;--windowed&lt;/code&gt; to create a GUI application without a console window. &lt;code&gt;--noconsole&lt;/code&gt; can also be utilized, but it simply hides the console window and there might be a brief appearance of it. You can also set the window size in your Tkinter code.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Title of the .exe file&lt;/strong&gt;: Specify the executable name with &lt;code&gt;--name&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  pyinstaller --onefile --name=SimpleCalculator calculator.py
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;testing-the-exe-setup-file&quot;&gt;Testing the .exe Setup File&lt;/h2&gt;
&lt;p&gt;We'll now test our executable file. I've converted the Python script to a .exe file using the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pyinstaller --onefile --windowed --name=SimpleCalculator --icon=calculator_icon.ico calculator.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;SimpleCalculator.exe&lt;/code&gt; file can be found in the &lt;code&gt;dist&lt;/code&gt; folder.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=15703158193762044820&quot; alt=&quot;pyinstl_execfile1&quot;&gt;&lt;/p&gt;
&lt;p&gt;Upon running the file, it works as intended.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=8593516799524454024&quot; alt=&quot;pyinstl_execfile2&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=1383139374120414111&quot; alt=&quot;pyinstl_execfile3&quot;&gt;&lt;/p&gt;
&lt;p&gt;To ensure compatibility, the file can be run on other systems as well.&lt;/p&gt;
&lt;p&gt;The following flowchart provides a comprehensive overview of the entire process from start to finish:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=15510702019602131858&quot; alt=&quot;pyinstl_flowchart&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;distributing-your-tkinter-application&quot;&gt;Distributing Your Tkinter Application&lt;/h2&gt;
&lt;p&gt;To include multiple files while creating an executable using PyInstaller, you can use the &lt;code&gt;--add-data&lt;/code&gt; option.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pyinstaller --onefile --add-data &quot;file1.extension;.&quot; --add-data &quot;file2.extension;.&quot; calculator.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;--add-data&lt;/code&gt; option allows you to specify the path to the extra file or folder you wish to include. Use a semicolon &lt;code&gt;;&lt;/code&gt; to distinguish the source path from the destination directory inside the executable. A dot &lt;code&gt;.&lt;/code&gt; indicates that the file should be copied to the same directory as the executable.&lt;/p&gt;
&lt;p&gt;It can be used to include .csv files or SQLite databases. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pyinstaller --onefile --add-data &quot;todo_data.db;.&quot; todo_list.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=8817162348252474682&quot; alt=&quot;pyinstl_add_run&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=603164746969197611&quot; alt=&quot;pyinstl_add_dist&quot;&gt;&lt;/p&gt;
&lt;p&gt;You have various options for distributing your .exe file to users:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Direct Downloads&lt;/strong&gt;: You can host the .exe file on your website or server and offer users a direct link to download it. This method gives you complete control over distribution.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GitHub Releases&lt;/strong&gt;: If your project is on GitHub, you can utilize the Releases feature to distribute your .exe file. Upload the file as an asset when creating a new release, and users can download it from the Releases page.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Third-Party Platforms&lt;/strong&gt;: Several third-party platforms allow file hosting and distribution, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Google Drive&lt;/strong&gt;: Upload the .exe file to Google Drive and share the download link.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dropbox&lt;/strong&gt;: Similar to Google Drive, you can upload the .exe file to Dropbox and share the link.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OneDrive&lt;/strong&gt;: Microsoft's OneDrive offers file hosting and sharing capabilities.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can download the executable file we made in this article by clicking &lt;a rel=&quot;nofollow&quot; href=&quot;[14]&quot; download=&quot;SimpleCalculator.exe&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusion-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In conclusion, creating a calculator application that can add, subtract, multiply and divide, using &lt;strong&gt;Tkinter&lt;/strong&gt; and converting it into a &lt;strong&gt;.exe file&lt;/strong&gt; using &lt;strong&gt;PyInstaller&lt;/strong&gt; is a straightforward process that opens up numerous opportunities for &lt;strong&gt;software distribution&lt;/strong&gt;. By following the steps outlined in this article, you've learned how to harness the power of Tkinter to build intuitive graphical user interfaces and leverage PyInstaller to package your Python scripts into &lt;strong&gt;standalone executables&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now that you've successfully created your calculator application and transformed it into a .exe file, it's time to share your creation with the world. Distributing your .exe files allows others to easily access and use your software, whether it's for personal or professional use. Whether you choose to host your files on your own website, share them via GitHub releases, or utilize third-party platforms, the possibilities for distribution are endless.&lt;/p&gt;
</description>
<category>Project Dev</category>
<guid isPermaLink="true">https://coderlegion.com/209/convert-tkinter-python-app-to-exe-file-pyinstaller-step-by-step-guide</guid>
<pubDate>Mon, 01 Apr 2024 06:11:39 +0000</pubDate>
</item>
<item>
<title>Tkinter ToDo GUI Application (Step by Step Guide)</title>
<link>https://coderlegion.com/208/tkinter-todo-gui-application-step-by-step-guide</link>
<description>&lt;p&gt;In this article, we'll dive into the world of &lt;strong&gt;Tkinter&lt;/strong&gt;, a popular GUI (Graphical User Interface) toolkit for Python, and harness its capabilities to build a robust &lt;strong&gt;to-do list application&lt;/strong&gt; from scratch. I'll walk you through each step, from designing a &lt;strong&gt;user-friendly interface&lt;/strong&gt; to adding crucial functions like &lt;strong&gt;task creation&lt;/strong&gt;, &lt;strong&gt;deletion&lt;/strong&gt; and &lt;strong&gt;prioritization&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;project-prerequisites&quot;&gt;Project Prerequisites&lt;/h2&gt;
&lt;p&gt;Before starting to build a to-do list app with Tkinter, make sure you have the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Python Installed: Have Python installed on your computer. Tkinter comes included with Python, so no separate installation is needed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For Windows&lt;/strong&gt;: Download and install Python from the &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.python.org/downloads/&quot;&gt;official website&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For Ubuntu&lt;/strong&gt;: You can download Python using the terminal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;     sudo apt update
     sudo apt install python3
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For MacOS&lt;/strong&gt;: You can download Python using Homebrew:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;     brew install python3
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;div-blue&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Note:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt; To confirm the installation, enter `python3 --version` in the terminal.&lt;/span&gt; &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Text Editor or IDE: Select a preferred text editor or IDE, such as Visual Studio Code or PyCharm, to write and execute Python code.&lt;/li&gt;
&lt;li&gt;Basic Python Skills: Learn core Python concepts: variables, data types, functions, and control flow.&lt;/li&gt;
&lt;li&gt;Tkinter Basics: Basic familiarity with Tkinter, including widgets and event handling, can be useful. You can learn through &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/tkinter.html&quot;&gt;Tkinter documentation&lt;/a&gt; or &lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/190/introduction-to-tkinter-library-in-python&quot;&gt;this article&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;designing-the-user-interface&quot;&gt;Designing the User Interface&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Importing necessary Libraries&lt;/strong&gt;&lt;br&gt;
Tkinter (&lt;code&gt;tk&lt;/code&gt;) is the go-to module for GUI applications, complemented by &lt;code&gt;ttk&lt;/code&gt; for themed widgets, offering a modern appearance. Utilizing the &lt;code&gt;messagebox&lt;/code&gt; module enables the display of user interaction messages. Additionally, SQLite3, a lightweight database engine, handles local data storage and management for our tasks.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Creating the Main Window&lt;/strong&gt;&lt;br&gt;
We create the main window using Tkinter, set its size, and instantiate the &lt;code&gt;TodoListApp&lt;/code&gt; class (discussed later) to integrate its functionalities. Finally, we start the event loop for user interaction.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;window = tk.Tk()
window.geometry(&quot;457x335&quot;)
app = TodoListApp(window)
window.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Adding a Title and necessary Frames and Labels&lt;/strong&gt;&lt;br&gt;
You can add a catchy title to your To-Do app. I have named it &quot;Todo List App&quot;. The app features two frames: one for entering new tasks and another for displaying existing ones. The new task frame includes labels for &quot;Task Name,&quot; &quot;Priority,&quot; and &quot;Deadline.&quot;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;self.window = window
window.title(&quot;Todo List App&quot;)
entry_frame = ttk.Frame(self.window)
entry_frame.pack(padx=10, pady=10, fill=tk.X)
ttk.Label(entry_frame, text=&quot;Task name:&quot;).grid(row=0, column=0, padx=5, pady=5)
ttk.Label(entry_frame, text=&quot;Priority:&quot;).grid(row=1, column=0, padx=5, pady=5)
ttk.Label(entry_frame, text=&quot;Deadline:&quot;).grid(row=2, column=0, padx=5, pady=5)
self.task_list_frame = ttk.Frame(self.window)
self.task_list_frame.pack(padx=10, pady=5, fill=tk.BOTH, expand=True)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Adding Widgets for Task Entry&lt;/strong&gt;&lt;br&gt;
To add a new task, provide the task name, priority, and deadline. All tasks require a name and set priority. For urgent tasks, a deadline is mandatory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;self.task_text = tk.StringVar()
self.task_entry = ttk.Entry(entry_frame, textvariable=self.task_text)
self.task_entry.grid(row=0, column=1, padx=5, pady=5)
ttk.Radiobutton(entry_frame, text=&quot;Urgent&quot;, variable=self.priority_selection, value=&quot;Urgent&quot;).grid(row=1, column=1, padx=5, pady=5)
ttk.Radiobutton(entry_frame, text=&quot;General&quot;, variable=self.priority_selection, value=&quot;General&quot;).grid(row=1, column=2, padx=5, pady=5)
self.task_deadline = tk.StringVar()
self.deadline_entry = ttk.Entry(entry_frame, textvariable=self.task_deadline)
self.deadline_entry.grid(row=2, column=1, padx=5, pady=5)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code snippet sets up the entry interface for users to input task details. It includes entry fields for users to specify the task name, radio buttons to specify the priority level (either &quot;Urgent&quot; or &quot;General&quot;), and another entry field for the deadline.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Adding Buttons&lt;/strong&gt;&lt;br&gt;
You will need 2 buttons to be included: one for adding a new task and another for deleting an existing task.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;add_button = ttk.Button(entry_frame, text=&quot;Add Task&quot;, command=self.add_task)
add_button.grid(row=3, column=0, columnspan=3, padx=5, pady=5)
delete_button = ttk.Button(self.window, text=&quot;Delete Tasks&quot;, command=self.delete_tasks)
delete_button.pack(pady=5)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, the first button, &quot;Add Task,&quot; triggers the &lt;code&gt;add_task&lt;/code&gt; method when clicked. The second button, &quot;Delete Tasks,&quot; triggers the &lt;code&gt;delete_tasks&lt;/code&gt; method upon activation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Displaying the List of Entered Tasks&lt;/strong&gt;&lt;br&gt;
Every task entered into the database table is retrieved and processed. A separate frame is generated for each task, within which labels are utilized to showcase the task details. Furthermore, a checkbutton is included for every task, enabling users to mark tasks as complete once they are fulfilled.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for task in tasks:
        task_id = task[0]
        task_text = task[1]
        task_priority = task[2]
        task_deadline = task[4]
        task_frame = ttk.Frame(self.task_list_frame)
        task_frame.pack(fill=tk.X, padx=5, pady=2)
        task_checkbutton = ttk.Checkbutton(task_frame, command=lambda id=task_id: self.select_task(id))
        task_checkbutton.grid(row=0, column=0)
        if task_priority == &quot;Urgent&quot; or (task_priority == &quot;General&quot; and task_deadline):
            task_label = ttk.Label(task_frame, text=(task_text+&quot;    (&quot;+task_deadline+&quot;)&quot;))
        else:
            task_label = ttk.Label(task_frame, text=task_text)
        task_label.grid(row=0, column=1, padx=5)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For each task, relevant details like &lt;code&gt;ID&lt;/code&gt;, &lt;code&gt;task&lt;/code&gt;, &lt;code&gt;priority&lt;/code&gt;, and &lt;code&gt;deadline&lt;/code&gt; are extracted. Frames are created to organize task information neatly. &lt;code&gt;task_checkbutton&lt;/code&gt; enable task completion marking, while task names are displayed as Labels. If urgent or with a deadline, task names include this information.&lt;/p&gt;
&lt;p&gt;This represents the expected appearance of the GUI:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=4674483976126799680&quot; alt=&quot;todo_gui&quot;&gt;&lt;/p&gt;
&lt;div class=&quot;div-green&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Tip:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt; Customize labels with different colors based on task priorities. See code at the end.&lt;/span&gt; &lt;/div&gt;
&lt;h2 id=&quot;implementing-functionality&quot;&gt;Implementing Functionality&lt;/h2&gt;
&lt;p&gt;The following functions are defined in the &lt;code&gt;TodoListApp&lt;/code&gt; class.&lt;/p&gt;
&lt;div class=&quot;div-green&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Tip:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt; It is best to encapsulate multiple functions in a class.&lt;/span&gt; &lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Create a Table in the SQLite Database&lt;/strong&gt;&lt;br&gt;
To store your tasks effectively, a database is necessary. We will proceed by creating a table within an SQLite database for this purpose.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;self.c.execute('''CREATE TABLE IF NOT EXISTS tasks (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    task TEXT NOT NULL,
                    priority TEXT,
                    initial_priority TEXT,
                    deadline TEXT
                )''')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;self.conn.commit()&lt;br&gt;
The &lt;code&gt;create_table&lt;/code&gt; function sets up a table named &lt;code&gt;tasks&lt;/code&gt; in the SQLite database. It includes columns for task details such as &lt;code&gt;ID&lt;/code&gt;, &lt;code&gt;task&lt;/code&gt; (name), &lt;code&gt;priority&lt;/code&gt;, &lt;code&gt;initial priority&lt;/code&gt;, and &lt;code&gt;deadline&lt;/code&gt;. This function ensures that the necessary table structure exists for storing task information and commits the changes to the database.&lt;/p&gt;
&lt;div class=&quot;div-red&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Caution:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt; Ensure that there is no existing table named `tasks` in the database as it may lead to data loss or corruption if the existing table structure is overwritten or altered unintentionally.&lt;/span&gt; &lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Function to Add Tasks&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To add a new task, provide the task name, priority, and deadline. All tasks require a name and set priority. For urgent tasks, a deadline is mandatory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;task_text = self.task_text.get().strip()
task_priority = self.priority_selection.get()
task_deadline = self.task_deadline.get().strip()
if task_text and (task_priority == &quot;General&quot; or (task_priority == &quot;Urgent&quot; and task_deadline)):
    self.c.execute(&quot;INSERT INTO tasks (task, priority, initial_priority, deadline) VALUES (?, ?, ?, ?)&quot;, (task_text, task_priority, task_priority, task_deadline))
    self.conn.commit()
    self.load_tasks()
    self.task_text.set(&quot;&quot;)
    self.priority_selection.set(&quot;&quot;)
    self.task_deadline.set(&quot;&quot;)
else:
    messagebox.showwarning(&quot;Warning&quot;, &quot;Task or Priority cannot be empty, and Urgent task must have a deadline.&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It collects task details from input fields. If the name isn't empty and the priority is valid, the task is added to the database. After insertion, the task list refreshes, and input fields reset. If inputs are invalid, a warning message appears.&lt;/p&gt;
&lt;p&gt;If task name or priority or deadline for an urgent task is not entered:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=9225277434351519448&quot; alt=&quot;todo_error_insert&quot;&gt;&lt;/p&gt;
&lt;p&gt;After successfully entering a task:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=5445632491705201640&quot; alt=&quot;todo_insert&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Function to Delete Tasks&lt;/strong&gt;&lt;br&gt;
To delete tasks, you click the &quot;Delete Tasks&quot; button, opening a window where you select tasks for removal. At least one task must be chosen before clicking &quot;Delete.&quot; After confirmation, the selected tasks are deleted from the SQLite table.&lt;/p&gt;
&lt;p&gt;This opens a Toplevel window:  &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;delete_window = tk.Toplevel(self.window)
delete_window.geometry(&quot;457x335&quot;)
delete_window.title(&quot;Delete Tasks&quot;)
task_list_frame = ttk.Frame(delete_window)     #to contain the list of tasks
task_list_frame.pack(padx=10, pady=10)
self.c.execute(&quot;SELECT id, task FROM tasks&quot;)      #retrieve tasks from database
tasks = self.c.fetchall()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This displays the retrieved tasks with checkboxes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for task_id, task_text in tasks:
    task_checkbutton = ttk.Checkbutton(task_list_frame, text=task_text, command=lambda id=task_id: update_selected_tasks(id))
    task_checkbutton.pack(anchor=&quot;w&quot;, padx=5, pady=2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=13763355634516336338&quot; alt=&quot;todo_del_window1&quot;&gt;&lt;/p&gt;
&lt;p&gt;This function removes the selected tasks from the table after verifying that at least one task has been chosen:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if not selected_task_ids:
     messagebox.showwarning(&quot;Warning&quot;, &quot;No tasks selected for deletion.&quot;)
     return
for task_id in selected_task_ids:
     self.c.execute(&quot;DELETE FROM tasks WHERE id=?&quot;, (task_id,))
     self.conn.commit()
     self.load_tasks()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If no task is selected:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=11183326691308680232&quot; alt=&quot;todo_del_window2&quot;&gt;&lt;/p&gt;
&lt;p&gt;Marking tasks 1 and 3 for deletion:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=4465095155001701158&quot; alt=&quot;todo_del_window3&quot;&gt;&lt;/p&gt;
&lt;p&gt;After successful deletion:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=11348943072900279369&quot; alt=&quot;todo_del_window4&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Function to Mark Tasks as Complete&lt;/strong&gt;&lt;br&gt;
When a task is marked as complete, it needs to be updated in the table as well.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;self.c.execute(&quot;SELECT priority, initial_priority FROM tasks WHERE id=?&quot;, (task_id,))
row = self.c.fetchone()
if row:
    current_priority, initial_priority = row
    if current_priority == 'Completed':
        new_priority = initial_priority
    else:
        new_priority = 'Completed'
    self.c.execute(&quot;UPDATE tasks SET priority=? WHERE id=?&quot;, (new_priority, task_id))
        self.conn.commit()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It fetches the task's &lt;code&gt;priority&lt;/code&gt; and &lt;code&gt;initial_priority&lt;/code&gt; from the database. If the task is marked as completed, it resets the priority to its initial state; otherwise, it marks the task as completed and updates its priority in the database.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=4704063977214190218&quot; alt=&quot;todo_complete&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;code-sample&quot;&gt;Code Sample&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3

class TodoListApp:
    def __init__(self, window):
        self.window = window
        self.window.title(&quot;Todo List App&quot;)
        self.conn = sqlite3.connect(&quot;todo.db&quot;)
        self.c = self.conn.cursor()
        self.create_table()
        self.selected_tasks = []
        self.priority_selection = tk.StringVar()
        self.create_widgets()
    
    def create_table(self):
        self.c.execute('''CREATE TABLE IF NOT EXISTS tasks (
                            id INTEGER PRIMARY KEY AUTOINCREMENT,
                            task TEXT NOT NULL,
                            priority TEXT,
                            initial_priority TEXT,
                            deadline TEXT
                        )''')
        self.conn.commit()
    
    def create_widgets(self):
        entry_frame = ttk.Frame(self.window)
        entry_frame.pack(padx=10, pady=10, fill=tk.X)
        ttk.Label(entry_frame, text=&quot;Task name:&quot;).grid(row=0, column=0, padx=5, pady=5)
        self.task_text = tk.StringVar()
        self.task_entry = ttk.Entry(entry_frame, textvariable=self.task_text)
        self.task_entry.grid(row=0, column=1, padx=5, pady=5)
        ttk.Label(entry_frame, text=&quot;Priority:&quot;).grid(row=1, column=0, padx=5, pady=5)
        ttk.Radiobutton(entry_frame, text=&quot;Urgent&quot;, variable=self.priority_selection, value=&quot;Urgent&quot;).grid(row=1, column=1, padx=5, pady=5)
        ttk.Radiobutton(entry_frame, text=&quot;General&quot;, variable=self.priority_selection, value=&quot;General&quot;).grid(row=1, column=2, padx=5, pady=5)
        ttk.Label(entry_frame, text=&quot;Deadline:&quot;).grid(row=2, column=0, padx=5, pady=5)
        self.task_deadline = tk.StringVar()
        self.deadline_entry = ttk.Entry(entry_frame, textvariable=self.task_deadline)
        self.deadline_entry.grid(row=2, column=1, padx=5, pady=5)
        add_button = ttk.Button(entry_frame, text=&quot;Add Task&quot;, command=self.add_task)
        add_button.grid(row=3, column=0, columnspan=3, padx=5, pady=5)
        self.task_list_frame = ttk.Frame(self.window)
        self.task_list_frame.pack(padx=10, pady=5, fill=tk.BOTH, expand=True)
        self.load_tasks()
        delete_button = ttk.Button(self.window, text=&quot;Delete Tasks&quot;, command=self.delete_tasks)
        delete_button.pack(pady=5)
        
    def load_tasks(self):
        for widget in self.task_list_frame.winfo_children():
            widget.destroy()
        self.c.execute(&quot;SELECT * FROM tasks&quot;)
        tasks = self.c.fetchall()
        for task in tasks:
            task_id = task[0]
            task_text = task[1]
            task_priority = task[2]
            task_deadline = task[4]
            task_frame = ttk.Frame(self.task_list_frame)
            task_frame.pack(fill=tk.X, padx=5, pady=2)
            task_checkbutton = ttk.Checkbutton(task_frame, command=lambda id=task_id: self.select_task(id))
            task_checkbutton.grid(row=0, column=0)
            if task_priority == &quot;Urgent&quot; or (task_priority == &quot;General&quot; and task_deadline):
                task_label = ttk.Label(task_frame, text=(task_text+&quot;    (&quot;+task_deadline+&quot;)&quot;))
            else:
                task_label = ttk.Label(task_frame, text=task_text)
            task_label.grid(row=0, column=1, padx=5)
            
            if task_priority == &quot;Urgent&quot;:
                task_label.config(foreground=&quot;red&quot;)
            else:
                task_label.config(foreground=&quot;blue&quot;)
            if task_priority == &quot;Completed&quot;:
                task_label.config(foreground=&quot;green&quot;)
                task_checkbutton.state(['selected'])
    
    def add_task(self):
        task_text = self.task_text.get().strip()
        task_priority = self.priority_selection.get()
        task_deadline = self.task_deadline.get().strip()
        if task_text and (task_priority == &quot;General&quot; or (task_priority == &quot;Urgent&quot; and task_deadline)):
            self.c.execute(&quot;INSERT INTO tasks (task, priority, initial_priority, deadline) VALUES (?, ?, ?, ?)&quot;, (task_text, task_priority, task_priority, task_deadline))
            self.conn.commit()
            self.load_tasks()
            self.task_text.set(&quot;&quot;)
            self.priority_selection.set(&quot;&quot;)
            self.task_deadline.set(&quot;&quot;)
        else:
            messagebox.showwarning(&quot;Warning&quot;, &quot;Task or Priority cannot be empty, and Urgent task must have a deadline.&quot;)
    
    def select_task(self, task_id):
        self.c.execute(&quot;SELECT priority, initial_priority FROM tasks WHERE id=?&quot;, (task_id,))
        row = self.c.fetchone()
        if row:
            current_priority, initial_priority = row
            if current_priority == 'Completed':
                new_priority = initial_priority
            else:
                new_priority = 'Completed'
            self.c.execute(&quot;UPDATE tasks SET priority=? WHERE id=?&quot;, (new_priority, task_id))
            self.conn.commit()
            self.load_tasks()

    def delete_tasks(self):
        delete_window = tk.Toplevel(self.window)
        delete_window.geometry(&quot;457x335&quot;)
        delete_window.title(&quot;Delete Tasks&quot;)
        task_list_frame = ttk.Frame(delete_window)
        task_list_frame.pack(padx=10, pady=10)
        self.c.execute(&quot;SELECT id, task FROM tasks&quot;)
        tasks = self.c.fetchall()
        selected_task_ids = []

        def update_selected_tasks(task_id):
            if task_id in selected_task_ids:
                selected_task_ids.remove(task_id)
            else:
                selected_task_ids.append(task_id)

        def delete_selected_tasks():
            if not selected_task_ids:
                messagebox.showwarning(&quot;Warning&quot;, &quot;No tasks selected for deletion.&quot;)
                return
            for task_id in selected_task_ids:
                self.c.execute(&quot;DELETE FROM tasks WHERE id=?&quot;, (task_id,))
            self.conn.commit()
            self.load_tasks()
            delete_window.destroy()

        for task_id, task_text in tasks:
            task_checkbutton = ttk.Checkbutton(task_list_frame, text=task_text, command=lambda id=task_id: update_selected_tasks(id))
            task_checkbutton.pack(anchor=&quot;w&quot;, padx=5, pady=2)

        delete_button = ttk.Button(delete_window, text=&quot;Delete&quot;, command=delete_selected_tasks)
        delete_button.pack(side=&quot;left&quot;, padx=5, pady=5)
        cancel_button = ttk.Button(delete_window, text=&quot;Cancel&quot;, command=delete_window.destroy)
        cancel_button.pack(side=&quot;right&quot;, padx=5, pady=5)

window = tk.Tk()
window.geometry(&quot;457x335&quot;)
app = TodoListApp(window)
window.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion-2&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In summary, crafting a Todo List App with Tkinter provides a practical introduction to Python GUI development. You've built an intuitive interface for a &lt;strong&gt;To-Do list app&lt;/strong&gt; with &lt;strong&gt;addition&lt;/strong&gt;, &lt;strong&gt;deletion&lt;/strong&gt;, and &lt;strong&gt;task completion&lt;/strong&gt; features. Using &lt;strong&gt;SQLite&lt;/strong&gt; for &lt;strong&gt;data storage&lt;/strong&gt;, you've showcased Python's &lt;strong&gt;versatility&lt;/strong&gt;. This project offers insights into &lt;strong&gt;user experience design&lt;/strong&gt;, beneficial for aspiring developers.&lt;/p&gt;
</description>
<category>Project Dev</category>
<guid isPermaLink="true">https://coderlegion.com/208/tkinter-todo-gui-application-step-by-step-guide</guid>
<pubDate>Wed, 27 Mar 2024 23:10:38 +0000</pubDate>
</item>
<item>
<title>Tkinter library in Python</title>
<link>https://coderlegion.com/190/tkinter-library-in-python</link>
<description>&lt;p&gt;In this article, we'll dive into the world of &lt;strong&gt;Graphical User Interface (GUI)&lt;/strong&gt; development using Python's &lt;strong&gt;Tkinter&lt;/strong&gt; library. Tkinter stands as a versatile and user-friendly tool for beginners and advanced programmers alike, simplifying the creation of &lt;strong&gt;GUI applications&lt;/strong&gt;. We aim to demystify the process of working with Tkinter, from understanding its core widgets to leveraging its strengths and navigating its limitations. By the end, you'll be equipped with the essentials of Tkinter to enhance your Python GUI development projects.&lt;/p&gt;
&lt;h2 id=&quot;understanding-tkinter&quot;&gt;Understanding Tkinter&lt;/h2&gt;
&lt;p&gt;Tkinter, short for &lt;strong&gt;Tk interface&lt;/strong&gt;, is a built-in Python library designed for creating interactive GUI applications. Tkinter, built on the Tk GUI toolkit, streamlines the creation of windows, buttons, menus, and other graphical elements. As an integral part of the Python standard library, Tkinter smoothly integrates with Python projects, requiring no extra installations, for a seamless GUI development experience. The official python tkinter documentation offers in-depth explanations of Tkinter modules, classes, and methods. &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/tkinter.html&quot;&gt;Visit Documentation&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;div-green&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Tip:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt;As you embark on your GUI development journey, start by sketching out the design and functionality of your application before jumping into the code. This can save time and streamline your development process.&lt;/span&gt; &lt;/div&gt;
&lt;h2 id=&quot;exploring-basic-widgets&quot;&gt;Exploring Basic Widgets&lt;/h2&gt;
&lt;p&gt;We'll begin by exploring some fundamental components you can construct using Tkinter. The following snippets must be preceeded by:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import tkinter as tk
window = tk.Tk()
window.geometry(&quot;457x335&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and followed by:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;window.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;div-red&quot;&gt; &lt;span class=&quot;alert-header&quot;&gt;Caution:&lt;/span&gt; &lt;span class=&quot;alert-body&quot;&gt;When working with widgets, remember to assign a unique name to each widget variable to avoid confusion, especially when your application starts to grow.&lt;/span&gt; &lt;/div&gt;
&lt;h3 id=&quot;label&quot;&gt;&lt;strong&gt;Label&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Presents either text or an image, lacking interactive features for users. For more information on &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/tkinter.html#label-widget&quot;&gt;label&lt;/a&gt; refer official documentation of python.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;label = tk.Label(window, text=&quot;This is a Label&quot;)
label.pack()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=15447304320421249354&quot; alt=&quot;Label&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;button&quot;&gt;&lt;strong&gt;Button&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;An interactive component that executes a specific operation upon being clicked, like dispatching form data or activating a particular function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def button_click():
    print(&quot;Button clicked&quot;)

button = tk.Button(window, text=&quot;Click here!&quot;, command=button_click)
button.pack()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=17225166072514634203&quot; alt=&quot;button&quot;&gt;&lt;/p&gt;
&lt;p&gt;After clicking the button:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=13782699684249808265&quot; alt=&quot;ButtonClicked&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;entry&quot;&gt;&lt;strong&gt;Entry&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;A text field where users can input text or numbers. This component is frequently utilized for entering information or executing search operations.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;entry = tk.Entry(window)
entry.pack()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=17774851110350440973&quot; alt=&quot;Entry&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;text&quot;&gt;&lt;strong&gt;Text&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;A text field that provides a multi-line text editing area for users to input or display text.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;text = tk.Text(window, height=5, width=30)
text.pack()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=8046130723076572707&quot; alt=&quot;text&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;scale&quot;&gt;&lt;strong&gt;Scale&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Enables users to choose a value from a spectrum by moving a slider control. It is useful for selecting values like volume, brightness, etc.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def update_value(value):
    label.config(text=f&quot;Volume Level: {value}&quot;)

scale = tk.Scale(window, from_=0, to=100, orient=tk.HORIZONTAL, command=update_value) #create a scale to select values from 0 to 100

scale.pack()
label = tk.Label(window, text=&quot;Volume Level: &quot;)
label.pack()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=18163681093508975768&quot; alt=&quot;Scale&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;spinbox&quot;&gt;&lt;strong&gt;Spinbox&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;A numerical input field with up and down arrow buttons for incrementing or decrementing the value.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;spinbox = tk.Spinbox(window, from_=0, to=10)
spinbox.pack()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=6830706622157727616&quot; alt=&quot;Spinbox&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;separator&quot;&gt;&lt;strong&gt;Separator&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;A horizontal or vertical line to visually separate sections or groups of widgets.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from tkinter import ttk #for themed widgets

label_1 = tk.Label(window, text=&quot;This is above the separator.&quot;)
label_1.pack()

separator = ttk.Separator(window, orient=tk.HORIZONTAL)
separator.pack(fill=tk.X)

label_2 = tk.Label(window, text=&quot;This is below the separator.&quot;)
label_2.pack()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=16298979966054953561&quot; alt=&quot;Separator&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;checkbutton&quot;&gt;&lt;strong&gt;Checkbutton&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;A checkbox enabling users to toggle between selecting and deselecting an option.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;check_var = tk.BooleanVar() #To keep track of the checkbox's state (checked or unchecked)
check_button = tk.Checkbutton(window, text=&quot;Checkbox&quot;, variable=check_var)
check_button.pack()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=9114035529065436677&quot; alt=&quot;Checkbutton&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;radiobutton&quot;&gt;&lt;strong&gt;Radiobutton&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;A group of radio buttons, ensuring that users can select only one option from a list of choices.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;radio_var = tk.StringVar() #To track which radio button is selected
radio_1 = tk.Radiobutton(window, text=&quot;Option 1&quot;, variable=radio_var, value=&quot;Option 1&quot;)
radio_2 = tk.Radiobutton(window, text=&quot;Option 2&quot;, variable=radio_var, value=&quot;Option 2&quot;)
radio_1.pack()
radio_2.pack()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=2612228386099183090&quot; alt=&quot;Radiobutton&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;listbox&quot;&gt;&lt;strong&gt;Listbox&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;A widget presenting a list of items, allowing users to select one or more options from the list.&lt;/p&gt;
&lt;h3 id=&quot;scrollbar&quot;&gt;&lt;strong&gt;Scrollbar&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Permits users to navigate through content surpassing the widget's visible boundaries, like in a text field or list.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;listbox = tk.Listbox(window)
scrollbar = tk.Scrollbar(window)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y) #scrollbar will be at the right side of the window and expands vertically
listbox.pack(side=tk.LEFT, fill=tk.BOTH) #listbox will be at the left side of the window and expands horizontally and vertically
listbox.config(yscrollcommand=scrollbar.set) #Attach scrollbar to listbox
scrollbar.config(command=listbox.yview)

for i in range(30):
    listbox.insert(tk.END, f&quot;Item {i+1}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=13063392361028412068&quot; alt=&quot;Listbox&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=489762057271802018&quot; alt=&quot;Scrollbar&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;colorchooser&quot;&gt;&lt;strong&gt;ColorChooser&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;A dialog for users to select a color. It provides a graphical interface for choosing colors using a palette or entering RGB values.&lt;/p&gt;
&lt;p&gt;from tkinter import colorchooser&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def choose_color():
    color = colorchooser.askcolor()
    print(&quot;Selected color:&quot;, color)

button = tk.Button(window, text=&quot;Choose Color&quot;, command=choose_color)
button.pack()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=8330473602676781386&quot; alt=&quot;ColorChooser&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;frame&quot;&gt;&lt;strong&gt;Frame&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;A container used to group and organize other widgets. It is frequently used for layout purposes, creating sections or divisions within a window.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;frame = tk.Frame(window, bg=&quot;lightblue&quot;, bd=5)
frame.pack()

label = tk.Label(frame, text=&quot;Inside the Frame&quot;, bg=&quot;lightblue&quot;)
label.pack()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=9882681441102070094&quot; alt=&quot;Frame&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;canvas&quot;&gt;&lt;strong&gt;Canvas&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Provides a drawing area for creating graphics, shapes, and custom elements. It is used for creating diagrams, charts, and interactive visualizations.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;canvas = tk.Canvas(window, width=200, height=100, bg=&quot;white&quot;)
canvas.pack()
canvas.create_rectangle(50, 25, 150, 75, fill=&quot;red&quot;) #draw a red-coloured rectangle
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=3077622398634848951&quot; alt=&quot;Canvas&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;panedwindow&quot;&gt;&lt;strong&gt;PanedWindow&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;A container for arranging multiple panes or frames with adjustable sizes. It allows users to resize panes by dragging the divider between them.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;paned_window = tk.PanedWindow(window, orient=tk.HORIZONTAL)
paned_window.pack(fill=tk.BOTH, expand=True) #will expand both horizontally and vertically
frame1 = tk.Frame(paned_window, width=228, height=200, background=&quot;red&quot;)
frame2 = tk.Frame(paned_window, width=228, height=200, background=&quot;blue&quot;)
paned_window.add(frame1)
paned_window.add(frame2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=11535792397148202103&quot; alt=&quot;PanedWindow1&quot;&gt;&lt;/p&gt;
&lt;p&gt;After dragging the divider to the left:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=11391496175646540405&quot; alt=&quot;PanedWindow2&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;menu&quot;&gt;&lt;strong&gt;Menu&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Creates a menu bar or dropdown menu with options and commands. It is commonly used to include navigation, settings and additional functionalities into the application's interface.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def print_something():
    print(&quot;You chose the first option&quot;)

menu_bar = tk.Menu(window)

file_menu = tk.Menu(menu_bar, tearoff=0)
file_menu.add_command(label=&quot;Print Something&quot;, command=print_something)
file_menu.add_separator()
file_menu.add_command(label=&quot;Exit&quot;, command=window.quit)
menu_bar.add_cascade(label=&quot;Click to see options&quot;, menu=file_menu)
window.config(menu=menu_bar)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=1591595257121153453&quot; alt=&quot;Menu&quot;&gt;&lt;/p&gt;
&lt;p&gt;After selecting &quot;Print Something&quot;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=5942132127197068255&quot; alt=&quot;MenuOutput&quot;&gt;&lt;/p&gt;
&lt;p&gt;These elements serve as fundamental components for Tkinter GUI applications, frequently employed across diverse projects to develop intuitive interfaces.&lt;/p&gt;
&lt;p&gt;To delve deeper into Tkinter and explore its capabilities, you can start with the following sections of the Python documentation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tkinter — Python interface to Tcl/Tk&lt;/strong&gt;: This section provides the foundational knowledge required to create GUI applications with Tkinter, including widget classes, event handling, and more &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/tkinter.html&quot;&gt;Python Tkinter Documentation&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Graphical User Interfaces with Tk&lt;/strong&gt;: This part of the documentation discusses the integration of Tk/Tcl with Python, offering insights into the architecture of Tkinter applications, the Tkinter module, and thematic widget extensions &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/tk.html&quot;&gt;Python GUI with Tk&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tkinter.ttk — Tk themed widgets&lt;/strong&gt;: For those interested in using themed widgets for a more modern GUI look, this section details the thematic widget set provided by Tk 8.5 and integrated into Tkinter &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/tkinter.ttk.html&quot;&gt;Themed Widgets&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conclusion-3&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Tkinter&lt;/strong&gt; is a versatile and user-friendly toolkit for &lt;strong&gt;Python GUI development&lt;/strong&gt;, offering a &lt;strong&gt;rich set of widgets&lt;/strong&gt;, &lt;strong&gt;cross-platform compatibility&lt;/strong&gt;, and &lt;strong&gt;seamless integration&lt;/strong&gt; with Python code. Despite its limitations, Tkinter remains a popular choice for developers looking for efficient creation of simple to moderately complex GUI applications.&lt;/p&gt;
</description>
<category>Project Dev</category>
<guid isPermaLink="true">https://coderlegion.com/190/tkinter-library-in-python</guid>
<pubDate>Tue, 12 Mar 2024 14:34:38 +0000</pubDate>
</item>
</channel>
</rss>