By: Nai Biao Zhou | Updated: 2023-03-06 | Comments | Related: > Python
Problem
Data analysis and business automation can utilize many Python libraries (Desai, 2019). Some business users must run small Python applications that perform many daily tasks to implement their business strategies. When running a Python application, they may prefer a responsive graphical user interface (GUI) that is user-friendly. Unfortunately, it seems Python developers mainly focus on web, mobile, and server-side programming, and desktop GUI application development does not get much attention (Moore & Harwani, 2019). Therefore, some Python developers may want to learn about building simple GUI tools.
Solution
We can use a standard GUI library for Python, i.e., tkinter, to create GUI applications. The tkinter library comes with Graphical Tool Kit controls (namely widgets) such as labels, entries, radio buttons, drop-down lists, and buttons. In addition, the tkinter.ttk module provides some advanced features like tree views and comboboxes. We need not learn a new programming language to use this library. As Love mentioned, tkinter is the easiest and best library for those new to GUI development (Love, 2018). However, the tkinter library may not be preferable for commercial applications due to limitations, such as a lack of more complex widgets.
The article walks through the steps to build a desktop application that can download stock market data from Yahoo Finance (Smigel, 2022). Figure 1 illustrates the layout of the GUI application. First, the textbox on the window allows users to enter a stock ticker symbol. Then, users should use radio boxes to select a dataset name of interest. Next, users must choose a period and an interval when downloading historical data. Finally, clicking the "Get Data" button triggers a callback function to download data and populates a tree view in the top-level window.
Figure 1 Basic GUI design for the desktop application
The tkinter library in Python defines many GUI elements and their functionality. With this library, we often employ these four steps to create a simple GUI application:
- Import the tkinter module.
- Create a main GUI window.
- Add widgets to the window.
- Run the window's main loop.
When adding widgets to the main window, we use the tkinter pack or grid geometry managers to arrange them. This article covers several standard widgets, including labels, entries, radio buttons, comboboxes, treeviews, scrollbars, and frames. We also introduce how to connect events that occurred on these widgets to Python callback functions.
In practice, the callback functions may not always be in the same file as the widget definitions. Without loss of generality, we organize all source code into two Python files. The Python file, "MSSQLTips_GUI_app.py," implements the four steps and produces a front-end view of the application. The file "MSSQLTips_GUI_backend.py," includes all callback functions that handle all events that occurred in the window.
The author uses Microsoft Visual Studio 2022 to edit Python scripts and test these scripts using Python 3.10 (64-bit) on Windows 10 Pro 10.0 <X64>. We design the wireframe using WireframeSketcher (Severin, 2023). The application accesses Yahoo Finance data through the "yfinance" package. To create an isolated environment for the project, the author added a virtual environment to the project using this requirement.txt:
appdirs==1.4.4 beautifulsoup4==4.11.1 certifi==2022.12.7 cffi==1.15.1 charset-normalizer==3.0.1 cryptography==39.0.0 frozendict==2.3.4 html5lib==1.1 idna==3.4 lxml==4.9.2 MarkupSafe==2.1.2 multitasking==0.0.11 numpy==1.24.1 pandas==1.5.3 pip==22.3.1 pycparser==2.21 python-dateutil==2.8.2 pytz==2022.7.1 requests==2.28.2 setuptools==65.5.0 six==1.16.0 soupsieve==2.3.2.post1 urllib3==1.26.14 webencodings==0.5.1 yfinance==0.2.9
1 - Creating a Main Window
Creating a simple GUI application using tkinter is not intimidating since this library has a collection of classes defining various GUI elements' functionality. The following code demonstrates the four steps in creating an application window. By saving and running this code, we should see a window with a greeting message inside, as shown in Figure 2. The top-level window (i.e., root) has a frame with a title bar, three control buttons in the top-right, and an area to hold other widgets. These buttons allow users to minimize, maximize, or close a window.
#1, Imports the tkinter module. import tkinter #2, Creates a main GUI window. root = tkinter.Tk() root.title('MSSQLtips Finance') #root.iconbitmap('SSQLtips.ico') root.geometry('420x460+300+300') root.resizable(0,0) #3, Adds widgets to the window. #3.1 Creates frames. greeting_frame = tkinter.Frame(root) #3.2 Arranges the frames. greeting_frame.pack() #3.3 Uses the greeting frame to organize widgets. #3.3.1 Adds a label to the greeting frame. greeting_label = tkinter.Label(greeting_frame, text='Welcome to MSSQLTips') #3.3.2 Arranges the label. greeting_label.pack() #4, Runs the window's main loop. root.mainloop()
Figure 2 The main window of the GUI application
The above code starts with importing the tkinter module. Next, the script creates a top-level GUI window by calling the Tk() function. The function returns a Python object that represents the window. Then, we invoke the object's methods to manipulate various attributes of the tkinter window. For example, the geometry() method defines the window's width, height, and position on the screen. In addition, the close button in the window's top right corner allows us to terminate the application.
We added two widgets to the window. i.e., a frame and a label. The frame is a simple rectangle that can hold other widgets. Since the project uses several widgets, we categorize these widgets into different groups and place one group into its respective frame. For example, this program adds the greeting frame to the top-level window and then adds the greeting label to the frame. To arrange these widgets, we invoke the geometry management pack command. When we use the default options of the command, the packer places widgets into their container sequentially. That said, when we add another frame to the window, the frame will be under the first frame.
Finally, the script calls the top-level window's mainloop() method to let the application be in an event listening loop. The event loop keeps the application window open and allows us to handle events that occurred. We can click the close button to terminate the event loop.
2 - Using Frames to Organize Widgets at Coding Level
The GUI application contains different kinds of widgets, and the wireframe indicates that we have the plan to arrange these widgets. We divide the window into several panels and work on each panel independently. In this case, changing the layout in one panel (for example, adding more radio buttons) should not affect the layout of others. Here are the six panels on the window, which stack on top of one another:
- The greeting panel contains a label that shows the greeting message.
- The textbox panel contains a label and a textbox for users to enter the stock ticker symbol.
- The radio panel contains a group of radio buttons.
- The combobox panel contains two labels and two comboboxes for users to select values of period and interval.
- The button panel contains a button that can trigger an API call.
- The tree view panel contains a treeview that visualizes the dataset returned from the API call.
We can use tkinter frame widgets to define the panels in the top-level window. A frame widget works like a container, which is responsible for arranging the position of other widgets. The following script creates and arranges the six frames corresponding to these panels. We pass the parent window as a parameter when creating these frames. We then use packers to place all these frames in the top-level window.
#3, Adds widgets to the window. #3.1 Creates frames. greeting_frame = tkinter.Frame(root) textbox_frame = tkinter.Frame(root) radio_frame = tkinter.LabelFrame(root, text='Select a dataset') combobox_frame = tkinter.Frame(root) button_frame = tkinter.Frame(root) treeview_frame = tkinter.Frame(root) #3.2 Arrange frames. greeting_frame.pack() textbox_frame.pack() radio_frame.pack() combobox_frame.pack() button_frame.pack() treeview_frame.pack()
The size and layout of the widgets in a frame determine the size of the frame. So, for example, the size of the greeting frame can be the same as the size of the label inside the frame. Note that we created a LabelFrame for the group of radio buttons. The LabelFrame widget, like the frame widget, can hold other widgets. Similar to the radio panel shown in the wireframe, the LabelFrame widget displays a label as part of the border around the area. This feature makes it an ideal container for radio buttons.
After placing all these frames in the top-level window, we can add widgets to these frames. The Python code in Section 1 demonstrated how to add a label widget to a frame. When we run the script, the application window should look like Figure 1. We cannot see the other five frames because the frames' width and height values are 0. The following sections introduce adding widgets to these frames.
3 - Creating a Single-line Textbox
According to the wireframe, the textbox panel contains a label that explains the purpose of the textbox and a single-line textbox for users to enter the stock ticker symbol. We use the Label and Entry widgets to create the label and textbox. We then use a geometry manager to organize these two GUI elements.
3.1 The Label Widget
We can use a tkinter label widget to display a text or image on the screen. For example, the following code creates a label inside the text box frame. The first argument to the widget is the parent container, i.e., the text box frame, and the second argument passes a string for displaying.
#3.4 Arrange the textbox frame. #3.4.1 Adds a label to the textbox frame. entry_label = tkinter.Label(textbox_frame, text='Stock Ticker Symbol:')
The abovementioned code passes a text message as an argument to the Label constructor. However, we may need to change the text after the script creates the widget. In this case, we can use the config() method to modify settings. This method enables us to change widget attributes dynamically. The following code demonstrates the use of this method.
greeting_label.config(text='Please Enter Stock Ticker Symbol:')
3.2 The Entry Widget
This exercise uses a tkinter entry widget to accept users' input. The widget allows users to enter a single-line text. For example, the following code creates a text box inside the text box frame. The parameter represents the parent frame in which we want to place the widget. We use the insert() method to add the initial text to the widget. The insert() method inserts the text at the given position. The first parameter specifies the character position, and the second represents a string to insert.
#3.4.2 Adds a text box to the textbox frame and set the initial value. text_entry = tkinter.Entry(textbox_frame) initial_value = 'GOOG' text_entry.insert(0, initial_value)
When revising the text in the entry widget, we can call the delete() method to remove all existing text and then add the new text. The following code demonstrates the process. Note that, tkinter.END represents the character position just after the last character in the entry widget. Therefore, the range (0, tkinter.END) corresponds to all characters in the widget.
text_entry.delete(0, tkinter.END) text_entry.insert(0, 'AAPL')
After users enter their text in the text box, we can use the get() method to fetch the text:
text_entry.get()
We can also bind the entry widget to a StringVar variable, which helps manage the value of the entry widget. The change in the variable's value automatically updates the text in the widget. The StringVar object has get() and set() methods, which operate data in the variable, and consequently set or get the entry text (Sharma, 2021). The following code demonstrates this technique:
text = tkinter.StringVar(textbox_frame) text_entry = tkinter.Entry(textbox_frame, textvariable = text) text.set('GOOG') text.get()
3.3 Geometry Management
The geometry management in tkinter means the interface's layout and design (Wheeler, 2011). The tkinter library provides three built-in geometry managers: the pack, grid, and place managers. The GUI application uses the pack and grid managers to arrange the widgets as specified. Note that a widget does not display if we add it to a frame without using a geometry manager.
The tkinter Pack Manager. The pack manager, a simple geometry manager, manages the widgets in blocks. We have already used this manager to place six frames in the top-level window. In this exercise, the pack manager stacks frames vertically. We also can use this manager to place widgets side by side. For example, the following code adds a label beside the entry:
#3.4.3 Defines the frame layout. entry_label.pack(side = tkinter.LEFT) text_entry.pack(side = tkinter.LEFT)
The script would create a window that should look like Figure 3.
Figure 3 The Pack Manager Arranges the Label and the Textbox Side by Side in the GUI.
The tkinter Grid Manager. The grid manager arranges the widgets into table-like structures. For example, Figure 4 illustrates a grid manager with four rows and three columns. Even though a pack manager can make such a layout, using a grid manager takes less effort. Moreover, a grid manager can use the columnspan or rowspan option to help widgets span more than one cell and therefore create complex forms.
Figure 4 A grid geometry manager that has four rows and three columns.
The following two lines of code arrange the label widget and the entry widget in the same row but in different columns. The grid() method informs the grid manager in which grid cells the widgets should live. When we run the script, the GUI should look like Figure 3. It is worth noting that we should not mix grid and pack in the same container.
#3.4.3 Defines the frame layout. entry_label.grid(row=0, column=0 text_entry.grid(row=0, column=1)
4 - Placing a Radio Button Group in the Frame
The GUI application allows users to pick a dataset name for downloading. The application provides two options, i.e., "Historical Data" and "Institutional Holders." These two options are mutually exclusive, and users must select one and only one of them. Therefore, we use a group of radio buttons to implement these requirements. All radio buttons in this group are associated with the same IntVar variable. In this case, clicking on one button sets the value of this variable. Correspondingly, this change deselects the previously selected button and selects the current one.
The following code adds a group of radio buttons in the radio frame. Note that the "Historical Data" radio button corresponds to a value of 1. By setting the value of the IntVar variable to 1, the application selects this option by default. When selecting the "Institutional Holders," we change the value of the IntVar variable to 2. Next, we use a grid manager to place these two radio buttons in the frame. The window should look like Figure 5. When there are many options in a radio group, we can use a loop to dynamically create all the radio buttons (Klein, 2022).
#3.5 Arranges the radio frame. #3.5.1 Set initial value. number = tkinter.IntVar() number.set(1) #3.5.2 Adds radio buttons to the radio frame. On selection we can display the value using one Label. radio_historical_data = tkinter.Radiobutton(radio_frame, text = 'Historical Data', value = 1, variable = number) radio_institutional_holders = tkinter.Radiobutton(radio_frame, text='Institutional Holders', value=2, variable = number) #3.5.3 Defines the frame layout. radio_historical_data.grid(row=0, column=0) radio_institutional_holders.grid(row=0, column=1)
Figure 5 Place a Group of Radio Buttons in the Frame
5 - Using Comboboxes to Choose One of Several Choices
After users pick the "Historical Data" dataset using radio buttons, we want them to select valid values of period and interval from predefined options. The combobox widget, provided via the tkinter.ttk module, can satisfy our requirements. We can make the widget behave like a drop-down list, which does not allow users to enter their values when instantiating the widget as read-only. By the way, the combobox widget only works with strings. Therefore, the widget automatically converts other data types to a string type before adding data to the options list.
The following code creates two comboboxes. We also create two labels to explain these two comboboxes. Next, we use a grid manager to arrange these four widgets in one row. Note that we use the current() method to set a default selection. When we run the script, the window should look like Figure 6.
from tkinter import ttk #3.6 Arranges the combobox frame. #3.6.1 Add labels, comboboxes and the get button to the frame. period_label = tkinter.Label(combobox_frame, text='Period:') period_combobox = ttk.Combobox(combobox_frame, value=['1d','5d','1mo'], state="readonly") interval_label = tkinter.Label(combobox_frame, text='Interval:') interval_combobox = ttk.Combobox(combobox_frame, value=['15m','30m','1h'], state="readonly") #3.6.2 Set default selection. period_combobox.current(0) interval_combobox.current(0) #3.6.3 Define the frame layout period_label.grid(row=0, column=0) period_combobox.grid(row=0, column=1) interval_label.grid(row=0, column=2) interval_combobox.grid(row=0, column=3)
Figure 6 Add Tow Comboboxes to the Frame.
We can use the get() method to obtain the selected option. The following two lines of code demonstrate the syntax of using this method. The method always returns a string. If there is no selection, we obtain an empty string. When we allow users to enter their values, the combobox widget works like the entry widget.
period = period_combobox.get() interval = interval_combobox.get()
6 - Adding a Button and Enabling Command Binding
After users configure the parameters for downloading a dataset, the GUI application provides a clickable button for users to start the downloading process. The button widget allows us to associate a callback function with an event using the command binding. We assign a function to the button's command option. The function gets called automatically when the left click event occurs on the button. The following code demonstrates the syntax:
# This function is for testing. We place all associated functions in a separated code file. def greeting(): greeting_label.config(text = 'You click on me.') #3.7 Arrange the button frame. #3.7.1 Adds a button to the button frame. get_button = tkinter.Button(button_frame, text = "Get Data", command = greeting) #3.7.2 Defines the frame layout. get_button.pack()
The Python code creates a button and places the button in the button frame using a pack manager. Meanwhile, we define a callback function and assign the function name to the command option of the button widget. Then, the program invokes the function automatically when the event occurs on the button. For example, when pressing the button, the callback function, greeting(), changes the text on the greeting label. Figure 7 shows the application window after we click on the button.
Figure 7 The GUI Responds to a Button Left Click Event
7 - Visualizing a Dataset Using a Treeview Widget
A data table is an efficient format for visualizing a small amount of quantitative data (Dunn, 2023). We can use a treeview widget to visualize a dataset. The following code demonstrates creating a table visualization using the ttk.Treeview widget. It is worth noting that the treeview widget can exhibit the hierarchy of items in a collection and respond to mouse-click actions.
#3.8 Arrange the treeview frame. #3.8.1 Adds a treeview to the treeview frame. columns = ['col0','col1','col2'] default_headings = ['Datetime', 'Open', 'Close'] tree = ttk.Treeview(treeview_frame, columns = columns, show = 'headings') # Defines the headings for index, col in enumerate(columns): tree.column(col, width = 100, anchor = 'center') tree.heading(col, text=default_headings[index]) #3.8.2 Add a scrollbar to the treeview frame. scrollbar = ttk.Scrollbar(treeview_frame, orient = tkinter.VERTICAL, command = tree.yview) tree.configure(yscroll = scrollbar.set) #3.8.3 Defines the frame layout. tree.grid(row = 0, column = 0) scrollbar.grid(row = 0, column = 1) #Add a fake list to the tree dataset = [['2023-02-14','45.23', '42.65'], ['2023-02-15','42.70', '48.92'], ['2023-02-16','22.46', '20.98'] ] for index in range(len(dataset)): tree.insert('', tkinter.END, values=dataset[index])
This code starts with defining a list of columns and headings. Then, we create a Treeview widget and pass the list of columns to the column option. Next, the for-loop specifies the width and heading for each column. After we create a vertical treeview scrollbar which allows users to view all rows in the table, we place the Treeview and Scrollbar widgets in the tree view frame. Finally, we generate a two-dimension list and use the insert() method to add the list to the treeview. The treeview should look like Figure 8.
Figure 8 Using a Treeview Widget to Display Data in Tabular Structure
8 - Event Handling for Widgets
The widgets must respond to events to make the application interactive. For example, in Section 6, we assigned the callback function to the button command option so that pressing the button can change the text on the label. However, we put the function in the same code file as the widget definitions and configurations. When the GUI is complicated, reading and maintaining the source code becomes challenging. Therefore, putting these callback functions in a separate code file is a good idea. This exercise puts all widget definitions into the "MSSQLTips_GUI_app.py" file and all event handlers into the "MSSQLTips_GUI_backend.py" file. To make all callback functions available to the widgets, we import one code file into another:
import MSSQLTips_GUI_backend as backend
8.1 Passing Arguments to a Callback Function
Section 6 assigned the callback function to the command option of the button widget. However, we may need to pass arguments to the callback function. For example, we want to pass variables and widgets to an event handler in another module so that the event handler can perform operations on these widgets. In this case, we can use a lambda expression that allows us to send multiple data through the callback function.
We first define a callback function that accepts arguments, as demonstrated in the following code. The callback function takes four parameters. Based on the value in the number parameter, the function changes the setting of the treeview and the two comboboxes. The callback function can also invoke another function to delete all rows in the treeview.
import tkinter import yfinance as yf import pandas as pd def clear_treeview(treeView): for row in treeView.get_children(): treeView.delete(row) def make_selection(treeView, number, period_combobox, interval_combobox): if number.get() == 1: column_headings = ['Datetime', 'Open', 'Close'] col_anchor = ['center', 'center', 'center'] period_combobox.config(state = "readonly") interval_combobox.config(state = "readonly") elif number.get() == 2: column_headings = ['Holder', 'Shares', 'Date Reported'] col_anchor = ['w', 'e', 'center'] period_combobox.config(state = tkinter.DISABLED) interval_combobox.config(state = tkinter.DISABLED) clear_treeview(treeView) for index, col in enumerate(column_headings): treeView.heading(index, text = col) treeView.column(index, anchor=col_anchor[index])
Next, we define and assign a lambda expression to the command option of the widget. The following code shows the syntax. Note that the lambda expression invokes the callback function and passes four arguments.
#3.5.2 Adds radio buttons to the radio frame. On selection we can display the value using one Label. radio_historical_data = tkinter.Radiobutton(radio_frame, text = 'Historical Data', value = 1, variable = number, command = lambda:backend.make_selection(tree, number, period_combobox, interval_combobox)) radio_institutional_holders = tkinter.Radiobutton(radio_frame, text='Institutional Holders', value=2, variable = number, command = lambda:backend.make_selection(tree, number, period_combobox, interval_combobox))
At this step, we should have two Python code files: MSSQLTips_GUI_app.py and MSSQLTips_GUI_backend.py. We also import the second file into the first one. Running the "MSSQLTips_GUI_app.py" displays a window that should look like Figure 8. The lambda expression executes when we click a radio button. The expression calls the make_selection() function and passes four arguments. Figure 9 illustrates how the window appearance changes when users select the "Institutional Holders" dataset.
Figure 9 The GUI Appearance Changes with the Radio Button Selection Changes
8.2 Using Event Binding to Assign a Function to an Event
The command binding does not work for all widgets since some widgets (for example labels) do not provide the command option. In addition, the command binding cannot handle all events. When a widget or an event does not support the command option, we can use the event binding technique in which we use the bind() method to assign a function to an event. By default, the tkinter passes the event detail to the handler. We can use a lambda expression to pass more arguments besides the event.
When the application starts, the default stock ticket is "GOOG." We want the application to delete this text when users click the textbox. However, after users enter a new ticket in this textbox, clicking on the box should not delete the text. The following two-step process demonstrates how we achieve this requirement.
We first define a callback function that accepts two arguments, as demonstrated in the following code. The first one is an event that contains the event details. The second one contains the value of the initial message. After the function receives these arguments, it compares the current string in the entry widget to the initial message. If they are the same, the function deletes the initial message.
def entry_click(event, initial_message): if event.widget.get() == initial_message: event.widget.delete(0, tkinter.END)
Next, we bind a lambda expression to the entry widget. The following code shows the syntax. Note that the lambda expression invokes the callback function and passes the initial message to the function.
#3.4.4 Bind to the event text_entry.bind("<ButtonPress-1>", lambda event, initial_message = initial_value: backend.entry_click(event, initial_value))
Running the "MSSQLTips_GUI_app.py" displays a window, as shown in Figure 8. The initial text "GOOG" disappears when we click on the textbox. We enter a new ticket, "AAPL," and click on the textbox again; the textbox should not change.
9 - The Complete Source Code
The exercise wants us to create a GUI application to download Yahoo Finance data. When users click the "Get Data" button, the application should invoke Yahoo Finance API and download a dataset according to users' selection. We use the button binding technique to assign a callback function to the command option of the button. The following code defines the callback function:
def get_data(tree, symbol_entry, number, period_combobox, interval_combobox): clear_treeview(tree) ticket = yf.Ticker(symbol_entry.get()) if ticket.institutional_holders is None: symbol_entry.insert(0, "*") symbol_entry.insert(tkinter.END, "*") return if number.get() == 1: period = period_combobox.get() interval = interval_combobox.get() data = ticket.history(period = period, interval = interval) if data.empty == False: data.reset_index(inplace = True) dataset = data[['Datetime', 'Open', 'Close']].copy() dataset['Datetime'] = dataset['Datetime'].dt.strftime("%Y-%m-%d %H:%M") dataset[['Open', 'Close']] = dataset[['Open', 'Close']].applymap(lambda x: '{0:.4f}'.format(x)) else: dataset = pd.DataFrame() elif number.get() == 2: dataset = ticket.institutional_holders[['Holder', 'Shares', 'Date Reported']].copy() dataset['Date Reported'] = dataset['Date Reported'].dt.date for index in range(len(dataset)): #https://tkdocs.com/tutorial/tree.html tree.insert('', tkinter.END, values=list(dataset.loc[index]))
Next, we assign the callback function in the "MSSQLTips_GUI_backend.py" file to the button definition in the "MSSQLTips_GUI_app" file, as shown in the following code:
#3.7.1 Adds a button to the button frame. get_button = tkinter.Button(button_frame, text = "Get Data", command = lambda:backend.get_data(tree, text_entry, number, period_combobox, interval_combobox))
At this step, the application implements all the business requirements. When we run the application and hit the "Get Data button" in the application window, we should receive a stock market dataset, as shown in Figure 10.
Figure 10 The GUI Application Downloads Data from Yahoo Finance
Many widgets share attributes such as dimensions, fonts, colors, sizes, and anchors that define the widget's appearance and behavior. So far, we have used the default settings. To make the application friendly, we can apply color to the GUI elements, adjust spaces between these elements, and select font styles for texts on the window. For demonstration purposes, the final product's appearance looks like Figure 11. When we select the "Institutional Holders" dataset, the window should look like Figure 12. Click here for the complete code.
Figure 11 The GUI Application Downloads the Historical Data
Figure 12 The GUI Application Downloads the Institutional Holders Dataset
Summary
We created a simple GUI tool to download stock market data from Yahoo Finance. The application allows users to enter a stock ticker symbol in a textbox and select a dataset name from a group of radio buttons. Next, users can click on the "Get Data" button to trigger a callback function that obtains the dataset for users and puts the result into a table. The application also uses several static labels to help users figure out how to work the application.
We started with creating a top-level window. We then placed six frames in the window according to the wireframe. The exercise used these frames to organize other widgets visually and at the coding level. Next, we added widgets to these frames and used geometry managers to arrange these widgets.
This article covered the basics of tkinter widgets, including frames, labels, radio buttons, comboboxes, buttons, and treeview. We also introduced the use of pack managers and grid managers. Next, we explored the command binding and event binding techniques in which we used a lambda expression to help pass arguments to the bound callback functions. Finally, the article provided the complete source code that covers all steps to develop the GUI application.
Reference
Desai, R. (2019). Top 10 Python Libraries for Data Science. https://towardsdatascience.com/top-10-python-libraries-for-data-science-cd82294ec266.
Dunn, K. (2023). Process Improvement Using Data. https://learnche.org/pid/.
Klein, B. (2022). Radio Buttons in Tkinter. https://python-course.eu/tkinter/radio-buttons-in-tkinter.php.
Love, D. (2018). Python Tkinter By Example. https://github.com/Dvlv/Tkinter-By-Example.
Moore, D. A. & Harwani, M. B. (2019). Python GUI Programming - A Complete Reference Guide. Birmingham, UK: Packt Publishing.
Severin, P. (2023). WireframeSketcher. https://wireframesketcher.com.
Sharma, Y. (2021). Tkinter StringVar with Examples – Tkinter Tutorial. https://www.askpython.com/python-modules/tkinter/stringvar-with-examples.
Smigel, L. (2022). yfinance Python Tutorial (2023). https://analyzingalpha.com/yfinance-python.
Wheeler, B. (2011). Tcl/Tk 8.5 Programming Cookbook. Birmingham, UK: Packt Publishing.
Next Steps
- The article covered the basics of the desktop application module in Python. The tkinter library currently comes with a module called "ttk," which provides widgets that look native on Windows. We should explore the tkinter modules for further learning. The author demonstrated how to change the appearance of the comboboxes and the tree view when users click on a radio button. We may practice adding a pop-up message for confirmation. The Python code used to create the GUI application was for demonstration purposes. Therefore, the article keeps things as simple as possible. In practice, we may use object-oriented styles and add more exception handlers. Further, the article did not cover user interface design. Knowing some basic principles of GUI design is always beneficial.
- Click here to download the complete code.
- Check out these related tips:
- Creating Animated Line Plots with Python
- How to Generate a QR Code with Power Apps and Azure Function with Python Runtime
- Import Data from an Excel file into a SQL Server Database using Python
- Connect to SQL Server with Python to Create Tables, Insert Data and Build Connection String
- Python Programming Tutorial with Top-Down Approach
- Export Large SQL Query Result with Python pyodbc and dask Libraries
About the author
This author pledges the content of this article is based on professional experience and not AI generated.
View all my tips
Article Last Updated: 2023-03-06