Python has a lot of GUI frameworks, but Tkinter is the only framework that’s built into the Python standard library. Tkinter has several strengths. It’s cross-platform, so the same code works on Windows, macOS, and Linux. Visual elements are rendered using native operating system elements, so applications built with Tkinter look like they belong on the platform where they’re run. Show
Although Tkinter is considered the de facto Python GUI framework, it’s not without criticism. One notable criticism is that GUIs built with Tkinter look outdated. If you want a shiny, modern interface, then Tkinter may not be what you’re looking for. However, Tkinter is lightweight and relatively painless to use compared to other frameworks. This makes it a compelling choice for building GUI applications in Python, especially for applications where a modern sheen is unnecessary, and the top priority is to quickly build something that’s functional and cross-platform. In this tutorial, you’ll learn how to:
Note: This tutorial is adapted from the chapter “Graphical User Interfaces” of Python Basics: A Practical Introduction to Python 3. The book uses Python’s built-in IDLE editor to create and edit Python files and interact with the Python shell. In this tutorial, references to IDLE have been removed in favor of more general language. The bulk of the material in this tutorial has been left unchanged, and you should have no problems running the example code from the editor and environment of your choice. Once you’ve mastered these skills by working through the exercises at the end of each section, you’ll tie everything together by building two applications. The first is a temperature converter, and the second is a text editor. It’s time to dive right in and learn how to build an application with Tkinter! Free Bonus: 5 Thoughts On Python Mastery, a free course for Python developers that shows you the roadmap and the mindset you’ll need to take your Python skills to the next level. Take the Quiz: Test your knowledge with our interactive “Python GUI Programming With Tkinter” quiz. Upon completion you will receive a score so you can track your learning progress over time: Take the Quiz » Building Your First Python GUI Application With TkinterThe foundational element of a Tkinter GUI is the window. Windows are the containers in which all other GUI elements live. These other GUI elements, such as text boxes, labels, and buttons, are known as widgets. Widgets are contained inside of windows. First, create a window that contains a single widget. Start up a new session and follow along! Note: The code examples in this tutorial have all been tested on Windows, macOS, and Ubuntu Linux 20.04 with Python version 3.10. If you’ve installed Python with the official installers available for Windows and macOS from python.org, then you should have no problem running the sample code. You can safely skip the rest of this note and continue with the tutorial! If you haven’t installed Python with the official installers, or there’s no official distribution for your system, then here are some tips for getting up and going. Python on macOS with Homebrew: The Python distribution for macOS available on Homebrew doesn’t come bundled with the Tcl/Tk dependency required by Tkinter. The default system version is used instead. This version may be outdated and prevent you from importing the Tkinter module. To avoid this problem, use the official macOS installer. Ubuntu Linux 20.04: To conserve memory space, the default version of the Python interpreter that comes pre-installed on Ubuntu Linux 20.04 has no support for Tkinter. However, if you want to continue using the Python interpreter bundled with your operating system, then install the following package:
This installs the Python GUI Tkinter module. Other Linux Flavors: If you’re unable to get a working Python installation on your flavor of Linux, then you can build Python with the correct version of Tcl/Tk from the source code. For a step-by-step walk-through of this process, check out the . You may also try using pyenv to manage multiple Python versions. With your Python shell open, the first thing you need to do is import the Python GUI Tkinter module: >>>
A window is an instance of Tkinter’s 02 class. Go ahead and create a new window and assign it to the variable 03:>>>
When you execute the above code, a new window pops up on your screen. How it looks depends on your operating system: Throughout the rest of this tutorial, you’ll see Windows screenshots. Remove adsAdding a WidgetNow that you have a window, you can add a widget. Use the 04 class to add some text to a window. Create a 05 widget with the text 06 and assign it to a variable called 07:>>>
The window you created earlier doesn’t change. You just created a 05 widget, but you haven’t added it to the window yet. There are several ways to add widgets to a window. Right now, you can use the 05 widget’s 10 method:>>>
The window now looks like this: When you pack a widget into a window, Tkinter sizes the window as small as it can be while still fully encompassing the widget. Now execute the following: >>>
Nothing seems to happen, but notice that no new prompt appears in the shell. 11 tells Python to run the Tkinter event loop. This method listens for events, such as button clicks or keypresses, and blocks any code that comes after it from running until you close the window where you called the method. Go ahead and close the window you’ve created, and you’ll see a new prompt displayed in the shell.Warning: When you work with Tkinter from a Python REPL, updates to windows are applied as each line is executed. This is not the case when a Tkinter program is executed from a Python file! If you don’t include 11 at the end of a program in a Python file, then the Tkinter application will never run, and nothing will be displayed. Alternatively, you can build your user interface incrementally in Python REPL by calling 13 after each step to reflect the change.Creating a window with Tkinter only takes a couple of lines of code. But blank windows aren’t very useful! In the next section, you’ll learn about some of the widgets available in Tkinter, and how you can customize them to meet your application’s needs. Check Your UnderstandingExpand the code blocks below to check your understanding: Exercise: Create a Tkinter windowShow/Hide Write a full Python script that creates a Tkinter window with the text 14.The window should look like this: Try this exercise now. You can expand the code block below to see a solution: Solution: Create a Tkinter windowShow/Hide Here’s one possible solution:
Keep in mind your code may look different. When you’re ready, you can move on to the next section. Working With WidgetsWidgets are the bread and butter of the Python GUI framework Tkinter. They’re the elements through which users interact with your program. Each widget in Tkinter is defined by a class. Here are some of the widgets available: Widget ClassDescription 05A widget used to display text on the screen 16A button that can contain text and can perform an action when clicked 17A text entry widget that allows only a single line of text 18A text entry widget that allows multiline text entry 19A rectangular region used to group related widgets or provide padding between widgetsYou’ll see how to work with each of these in the following sections, but keep in mind that Tkinter has many more widgets than those listed here. The widget’s choice gets even more complicated when you account for a whole new set of themed widgets. In the remaining part of this tutorial, you’re only going to use Tkinter’s classic widgets, though. If you’d like to learn more about the two widget types, then you can expand the collapsible section below: Classic vs Themed WidgetsShow/Hide It’s worth noting that there are currently two broad categories of widgets in Tkinter:
Tkinter’s classic widgets are highly customizable and straightforward, but they tend to appear dated or somewhat foreign on most platforms today. If you’d like to take advantage of widgets with a native look and feel familiar to users of a given operating system, then you might want to check out the themed widgets. Most of the themed widgets are near drop-in replacements for their legacy counterparts, but with a more modern look. You can also use a few brand-new widgets, such as the , which weren’t available in Tkinter before. At the same time, you’ll need to continue using some of the classic widgets that don’t have a themed alternative. Note: Themed widgets in the 24 module use the operating system’s native look and feel by default. However, you can change their theme for a customized visual appearance, such as light and dark modes. A theme is a collection of reusable style definitions, which you can think of as a Cascading Style Sheet (CSS) for Tkinter.Making the new widgets themable meant extracting most of their style information into separate objects. On the one hand, such a separation of concerns is a desired property in the library’s design, but on the other hand, it introduces an additional abstraction layer, which makes themed widgets more difficult to style than the classic ones. When working with regular and themed widgets in Tkinter, it’s customary to declare the following aliases for the Tkinter packages and modules: >>>
Aliases like this let you explicitly refer to either 04 or 26, for example, in one program depending on your needs:>>>
However, you may sometimes find it more convenient to use a wildcard import ( 27) to automatically override all legacy widgets with the themed ones where possible, like so:>>>
Now, you don’t have to prefix the widget’s class name with its corresponding Python module. You’ll always create a themed widget as long as it’s available, or you’ll fall back to the classic widget otherwise. The two import statements above must be placed in the specified order to have an effect. Because of that, wildcard imports are considered a bad practice, which should generally be avoided unless used consciously. For a full list of Tkinter widgets, check out Basic Widgets and More Widgets in the TkDocs tutorial. Even though it describes themed widgets introduced in Tcl/Tk 8.5, most of the information there should also apply to the classic widgets. Fun Fact: Tkinter literally stands for “Tk interface” because it’s a Python binding or a programming interface to the Tk library in the Tcl scripting language. For now, take a closer look at the 05 widget.Remove adsDisplaying Text and Images With >>> import tkinter as tk 05 Widgets 05 widgets are used to display text or images. The text displayed by a 05 widget can’t be edited by the user. It’s for display purposes only. As you saw in the example at the beginning of this tutorial, you can create a 05 widget by instantiating the 05 class and passing a string to the 34 parameter: 0 05 widgets display text with the default system text color and the default system text background color. These are typically black and white, respectively, but you may see different colors if you’ve changed these settings in your operating system.You can control 05 text and background colors using the 37 and 38 parameters: 1There are numerous valid color names, including:
Many of the HTML color names work with Tkinter. For a full reference, including macOS- and Windows-specific system colors that the current system theme controls, check out the colors manual page. You can also specify a color using : 2This sets the label background to a nice, light blue color. Hexadecimal RGB values are more cryptic than named colors, but they’re also more flexible. Fortunately, there are tools available that make getting hexadecimal color codes relatively painless. If you don’t feel like typing out 37 and 38 all the time, then you can use the shorthand 47 and 48 parameters to set the foreground and background colors: 3You can also control the width and height of a label with the 49 and 50 parameters: 4Here’s what this label looks like in a window: It may seem strange that the label in the window isn’t square even though the width and height are both set to 51. This is because the width and height are measured in text units. One horizontal text unit is determined by the width of the character 52, or the number zero, in the default system font. Similarly, one vertical text unit is determined by the height of the character 52.Note: For width and height measurements, Tkinter uses text units, instead of something like inches, centimeters, or pixels, to ensure consistent behavior of the application across platforms. Measuring units by the width of a character means that the size of a widget is relative to the default font on a user’s machine. This ensures the text fits properly in labels and buttons, no matter where the application is running. Labels are great for displaying some text, but they don’t help you get input from a user. The next three widgets that you’ll learn about are all used to get user input. Remove adsDisplaying Clickable Buttons With >>> import tkinter as tk 16 Widgets 16 widgets are used to display clickable buttons. You can configure them to call a function whenever they’re clicked. You’ll cover how to call functions from button clicks in the next section. For now, take a look at how to create and style a button.There are many similarities between 16 and 05 widgets. In many ways, a button is just a label that you can click! The same keyword arguments that you use to create and style a 05 will work with 16 widgets. For example, the following code creates a button with a blue background and yellow text. It also sets the width and height to 60 and 61 text units, respectively: 5Here’s what the button looks like in a window: Pretty nifty! You can use the next two widgets to collect text input from a user. Getting User Input With >>> import tkinter as tk 17 WidgetsWhen you need to get a little bit of text from a user, like a name or an email address, use an 17 widget. It’ll display a small text box that the user can type some text into. Creating and styling an 17 widget works pretty much exactly like with 05 and 16 widgets. For example, the following code creates a widget with a blue background, some yellow text, and a width of 67 text units: 6The interesting bit about 17 widgets isn’t how to style them, though. It’s how to use them to get input from a user. There are three main operations that you can perform with 17 widgets:
The best way to get an understanding of 17 widgets is to create one and interact with it. Open up a Python shell and follow along with the examples in this section. First, import 20 and create a new window:>>> 7Now create a 05 and an 17 widget:>>> 8The 05 describes what sort of text should go in the 17 widget. It doesn’t enforce any sort of requirements on the 17, but it tells the user what your program expects them to put there. You need to 10 the widgets into the window so that they’re visible:>>> 9Here’s what that looks like: Notice that Tkinter automatically centers the label above the 17 widget in the window. This is a feature of 10, which you’ll learn more about in later sections.Click inside the 17 widget with your mouse and type 84:Now you’ve got some text entered into the 17 widget, but that text hasn’t been sent to your program yet. You can use 70 to retrieve the text and assign it to a variable called 87:>>> 0You can delete text as well. This 71 method takes an integer argument that tells Python which character to remove. For example, the code block below shows how 89 deletes the first character from 17:>>> 1The text remaining in the widget is now 91:Note that, just like Python string objects, text in an 17 widget is indexed starting with 52.If you need to remove several characters from an 17, then pass a second integer argument to 71 indicating the index of the character where deletion should stop. For example, the following code deletes the first four letters in 17:>>> 2The remaining text now reads 97: 98 works just like . The first argument determines the starting index, and the deletion continues up to but not including the index passed as the second argument. Use the special constant 99 for the second argument of 71 to remove all text in 17:>>> 3You’ll now see a blank text box: On the opposite end of the spectrum, you can also insert text into an 17 widget:>>> 4The window now looks like this: The first argument tells 72 where to insert the text. If there’s no text in 17, then the new text will always be inserted at the beginning of the widget, no matter what value you pass as the first argument. For example, calling 72 with 06 as the first argument instead of 52, as you did above, would’ve generated the same output.If 17 already contains some text, then 72 will insert the new text at the specified position and shift all existing text to the right:>>> 5The widget text now reads 84: 17 widgets are great for capturing small amounts of text from a user, but because they’re only displayed on a single line, they’re not ideal for gathering large amounts of text. That’s where 18 widgets come in!Remove adsGetting Multiline User Input With >>> import tkinter as tk 18 Widgets 18 widgets are used for entering text, just like 17 widgets. The difference is that 18 widgets may contain multiple lines of text. With a 18 widget, a user can input a whole paragraph or even several pages of text! Just like with 17 widgets, you can perform three main operations with 18 widgets:
Although the method names are the same as the 17 methods, they work a bit differently. It’s time to get your hands dirty by creating a 18 widget and seeing what it can do.Note: Do you still have the window from the previous section open? If so, then you can close it by executing the following: >>> 6You can also close it manually by clicking the Close button. In your Python shell, create a new blank window and pack a 25 widget into it:>>> 7Text boxes are much larger than 17 widgets by default. Here’s what the window created above looks like:Click anywhere inside the window to activate the text box. Type in the word 27. Then press Enter and type 28 on the second line. The window should now look like this:Just like with 17 widgets, you can retrieve the text from a 18 widget using 70. However, calling 70 with no arguments doesn’t return the full text in the text box like it does for 17 widgets. It raises an exception:>>> 8 34 requires at least one argument. Calling 70 with a single index returns a single character. To retrieve several characters, you need to pass a start index and an end index. Indices in 18 widgets work differently than in 17 widgets. Since 18 widgets can have several lines of text, an index must contain two pieces of information:
Line numbers start with 39, and character positions start with 52. To make an index, you create a string of the form 41, replacing 42 with the line number and 43 with the character number. For example, 44 represents the first character on the first line, and 45 represents the fourth character on the second line.Use the index 44 to get the first letter from the text box that you created earlier:>>> 9There are five letters in the word 27, and the character number of 48 is 49, since character numbers start from 52, and the word 27 starts at the first position in the text box. Just like with Python string slices, in order to get the entire word 27 from the text box, the end index must be one more than the index of the last character to be read.So, to get the word 27 from the text box, use 44 for the first index and 55 for the second index:>>> 0To get the word 28 on the second line of the text box, change the line numbers in each index to 57:>>> 1To get all of the text in a text box, set the starting index in 44 and use the special 99 constant for the second index:>>> 2Notice that text returned by 70 includes any newline characters. You can also see from this example that every line in a 18 widget has a newline character at the end, including the last line of text in the text box. 71 is used to delete characters from a text box. It works just like 71 for 17 widgets. There are two ways to use 71:
Using the single-argument version, you pass to 71 the index of a single character to be deleted. For example, the following deletes the first character, 67, from the text box:>>> 3The first line of text in the window now reads 68:With the two-argument version, you pass two indices to delete a range of characters starting at the first index and up to, but not including, the second index. For example, to delete the remaining 68 on the first line of the text box, use the indices 44 and 71:>>> 4Notice that the text is gone from the first line. This leaves a blank line followed the word 28 on the second line:Even though you can’t see it, there’s still a character on the first line. It’s a newline character! You can verify this using 70:>>> 5If you delete that character, then the rest of the contents of the text box will shift up a line: >>> 3Now, 28 is on the first line of the text box:Try to clear out the rest of the text in the text box. Set 44 as the start index and use 99 for the second index:>>> 7The text box is now empty: You can insert text into a text box using 72:>>> 8This inserts the word 27 at the beginning of the text box, using the same 79 format used by 70 to specify the insertion position:Check out what happens if you try to insert the word 28 on the second line:>>> 9Instead of inserting the text on the second line, the text is inserted at the end of the first line: If you want to insert text onto a new line, then you need to insert a newline character manually into the string being inserted: >>> 0Now 28 is on the second line of the text box: 72 will do one of two things:
It’s usually impractical to try and keep track of what the index of the last character is. The best way to insert text at the end of a 18 widget is to pass 99 to the first parameter of 72:>>> 1Don’t forget to include the newline character ( 87) at the beginning of the text if you want to put it on a new line:>>> 2 05, 16, 17, and 18 widgets are just a few of the widgets available in Tkinter. There are several others, including widgets for checkboxes, radio buttons, scroll bars, and progress bars. For more information on all of the available widgets, see the Additional Widgets list in the section.Remove adsAssigning Widgets to Frames With >>> import tkinter as tk 19 WidgetsIn this tutorial, you’re going to work with only five widgets:
These are the four you’ve seen so far plus the 19 widget. 19 widgets are important for organizing the layout of your widgets in an application.Before you get into the details about laying out the visual presentation of your widgets, take a closer look at how 19 widgets work, and how you can assign other widgets to them. The following script creates a blank 19 widget and assigns it to the main application window: 3 02 packs the frame into the window so that the window sizes itself as small as possible to encompass the frame. When you run the above script, you get some seriously uninteresting output:An empty 19 widget is practically invisible. Frames are best thought of as containers for other widgets. You can assign a widget to a frame by setting the widget’s 04 attribute: 4To get a feel for how this works, write a script that creates two 19 widgets called 06 and 07. In this script, 06 contains a label with the text 09, and 07 contains the label 11. Here’s one way to do this: 5Note that 06 is packed into the window before 07. The window that opens shows the label in 06 above the label in 07:Now see what happens when you swap the order of 16 and 17: 6The output looks like this: Now 18 is on top. Since 18 is assigned to 07, it moves to wherever 07 is positioned.All four of the widget types that you’ve learned about— 05, 16, 17, and 18—have a 04 attribute that’s set when you instantiate them. That way, you can control which 19 a widget is assigned to. 19 widgets are great for organizing other widgets in a logical manner. Related widgets can be assigned to the same frame so that, if the frame is ever moved in the window, then the related widgets stay together.Note: If you omit the 04 argument when creating a new widget instance, then it’ll be placed inside of the top-level window by default.In addition to grouping your widgets logically, 19 widgets can add a little flare to the visual presentation of your application. Read on to see how to create various borders for 19 widgets.Remove adsAdjusting Frame Appearance With Reliefs 19 widgets can be configured with a 33 attribute that creates a border around the frame. You can set 33 to be any of the following values:
To apply the border effect, you must set the 40 attribute to a value greater than 39. This attribute adjusts the width of the border in pixels. The best way to get a feel for what each effect looks like is to see them for yourself. Here’s a script that packs five 19 widgets into a window, each with a different value for the 33 argument: 7Here’s a breakdown of this script:
The window produced by the above script looks like this: In this image, you can see the following effects:
These effects give your Python GUI Tkinter application a bit of visual appeal. Understanding Widget Naming ConventionsWhen you create a widget, you can give it any name you like, as long as it’s a valid Python identifier. It’s usually a good idea to include the name of the widget class in the variable name that you assign to the widget instance. For example, if a 05 widget is used to display a user’s name, then you might name the widget 65. An 17 widget used to collect a user’s age might be called 67.Note: Sometimes, you may define a new widget without assigning it to a variable. You’ll call its 10 method directly on the same line of code:>>> 8This might be helpful when you don’t intend to refer to the widget’s instance later on. Due to automatic memory management, Python would normally such unassigned objects, but Tkinter prevents that by registering every new widget internally. When you include the widget class name in the variable name, you help yourself and anyone else who needs to read your code to understand what type of widget the variable name refers to. However, using the full name of the widget class can lead to long variable names, so you may want to adopt a shorthand for referring to each widget type. For the rest of this tutorial, you’ll use the following shorthand prefixes to name widgets: Widget ClassVariable Name PrefixExample 05 70 71 16 73 74 17 76 77 18 79 80 19 82 83In this section, you learned how to create a window, use widgets, and work with frames. At this point, you can make some plain windows that display messages, but you’ve yet to create a full-blown application. In the next section, you’ll learn how to control the layout of your applications using Tkinter’s powerful geometry managers. Check Your UnderstandingExpand the code block below for an exercise to check your understanding: Exercise: Create an Entry widget and insert some textShow/Hide Write a complete script that displays an 17 widget that’s 40 text units wide and has a white background and black text. Use 72 to display text in the widget that reads 86.The output window should look like this: Try this exercise now. You can expand the code block below to see a solution: Solution: Create an Entry widget and insert some textShow/Hide There are a couple of ways to solve this exercise. Here’s one solution that uses the 48 and 47 parameters to set the 17 widget’s background and foreground colors: 9This solution is great because it explicitly sets the background and foreground colors for the 17 widget.On most systems, the default background color for an 17 widget is white, and the default foreground color is black. So, you might be able to generate the same window with the 48 and 47 parameters left out: 0Keep in mind your code may look different. When you’re ready, you can move on to the next section. Remove adsControlling Layout With Geometry ManagersUp until now, you’ve been adding widgets to windows and 19 widgets using 10, but you haven’t learned what exactly this method does. Let’s clear things up! Application layout in Tkinter is controlled with geometry managers. While 10 is an example of a geometry manager, it isn’t the only one. Tkinter has two others:
Each window or 19 in your application can use only one geometry manager. However, different frames can use different geometry managers, even if they’re assigned to a frame or window using another geometry manager. Start by taking a closer look at 10.The >>> import tkinter as tk 10 Geometry ManagerThe 10 geometry manager uses a packing algorithm to place widgets in a 19 or window in a specified order. For a given widget, the packing algorithm has two primary steps:
10 is powerful, but it can be difficult to visualize. The best way to get a feel for 10 is to look at some examples. See what happens when you 10 three 05 widgets into a 19: 1 10 places each 19 below the previous one by default, in the order that they’re assigned to the window:Each 19 is placed at the topmost available position. Therefore, the red 19 is placed at the top of the window. Then the yellow 19 is placed just below the red one and the blue 19 just below the yellow one.There are three invisible parcels, each containing one of the three 19 widgets. Each parcel is as wide as the window and as tall as the 19 that it contains. Because no anchor point was specified when 10 was called for each 18 they’re all centered inside of their parcels. That’s why each 19 is centered in the window. 10 accepts some keyword arguments for more precisely configuring widget placement. For example, you can set the 21 keyword argument to specify in which direction the frames should fill. The options are 22 to fill in the horizontal direction, 23 to fill vertically, and 24 to fill in both directions. Here’s how you would stack the three frames so that each one fills the whole window horizontally: 2Notice that the 49 is not set on any of the 19 widgets. 49 is no longer necessary because each frame sets 10 to fill horizontally, overriding any width you may set.The window produced by this script looks like this: One of the nice things about filling the window with 10 is that the fill is responsive to window resizing. Try widening the window generated by the previous script to see how this works. As you widen the window, the width of the three 19 widgets grow to fill the window:Notice, though, that the 19 widgets don’t expand in the vertical direction.The 55 keyword argument of 10 specifies on which side of the window the widget should be placed. These are the available options:
If you don’t set 55, then 10 will automatically use 34 and place new widgets at the top of the window, or at the topmost portion of the window that isn’t already occupied by a widget. For example, the following script places three frames side by side from left to right and expands each frame to fill the window vertically: 3This time, you have to specify the 50 keyword argument on at least one of the frames to force the window to have some height.The resulting window looks like this: Just like when you set 42 to make the frames responsive when you resized the window horizontally, you can set 43 to make the frames responsive when you resize the window vertically:To make the layout truly responsive, you can set an initial size for your frames using the 49 and 50 attributes. Then, set the 21 keyword argument of 10 to 24 and set the 49 keyword argument to 50: 4When you run the above script, you’ll see a window that initially looks the same as the one you generated in the previous example. The difference is that now you can resize the window however you want, and the frames will expand and fill the window responsively: Pretty cool! Remove adsThe >>> greeting = tk.Label(text="Hello, Tkinter") 97 Geometry ManagerYou can use 97 to control the precise location that a widget should occupy in a window or 19. You must provide two keyword arguments, 54 and 55, which specify the x- and y-coordinates for the top-left corner of the widget. Both 54 and 55 are measured in pixels, not text units.Keep in mind that the origin, where 54 and 55 are both 52, is the top-left corner of the 19 or window. So, you can think of the 55 argument of 97 as the number of pixels from the top of the window, and the 54 argument as the number of pixels from the left edge of the window.Here’s an example of how the 97 geometry manager works: 5Here’s how this code works:
Here’s the window that the code produces: Note that if you run this code on a different operating system that uses different font sizes and styles, then the second label might become partially obscured by the window’s edge. That’s why 97 isn’t used often. In addition to this, it has two main drawbacks:
One of the main challenges of cross-platform GUI development is making layouts that look good no matter which platform they’re viewed on, and 97 is a poor choice for making responsive and cross-platform layouts.That’s not to say you should never use 97! In some cases, it might be just what you need. For example, if you’re creating a GUI interface for a map, then 97 might be the perfect choice to ensure widgets are placed at the correct distance from each other on the map. 10 is usually a better choice than 97, but even 10 has some downsides. The placement of widgets depends on the order in which 10 is called, so it can be difficult to modify existing applications without fully understanding the code controlling the layout. The 98 geometry manager solves a lot of these issues, as you’ll see in the next section.The >>> greeting = tk.Label(text="Hello, Tkinter") 98 Geometry ManagerThe geometry manager you’ll likely use most often is 98, which provides all the power of 10 in a format that’s easier to understand and maintain. 98 works by splitting a window or 19 into rows and columns. You specify the location of a widget by calling 98 and passing the row and column indices to the 94 and 95 keyword arguments, respectively. Both row and column indices start at 52, so a row index of 39 and a column index of 57 tells 98 to place a widget in the third column of the second row.The following script creates a 3 × 3 grid of frames with 05 widgets packed into them: 6Here’s what the resulting window looks like: You’re using two geometry managers in this example. Each frame is attached to 03 with the 98 geometry manager: 7Each 03 is attached to its master 19 with 10: 8The important thing to realize here is that even though 98 is called on each 19 object, the geometry manager applies to the 03 object. Similarly, the layout of each 56 is controlled with the 10 geometry manager.The frames in the previous example are placed tightly next to one another. To add some space around each frame, you can set the padding of each cell in the grid. Padding is just some blank space that surrounds a widget and visually sets its content apart. The two types of padding are external and internal padding. External padding adds some space around the outside of a grid cell. It’s controlled with two keyword arguments to 98:
Both 12 and 13 are measured in pixels, not text units, so setting both of them to the same value will create the same amount of padding in both directions. Try to add some padding around the outside of the frames from the previous example: 9Here’s the resulting window: 10 also has 12 and 13 parameters. The following code is nearly identical to the previous code, except that you add five pixels of additional padding around each label in both the 54 and 55 directions: 0The extra padding around the 05 widgets gives each cell in the grid a little bit of breathing room between the 19 border and the text in the label:That looks pretty nice! But if you try and expand the window in any direction, then you’ll notice that the layout isn’t very responsive: The whole grid stays at the top-left corner as the window expands. By using 23 and 24 on the 03 object, you can adjust how the rows and columns of the grid grow as the window is resized. Remember, the grid is attached to 03, even though you’re calling 98 on each 19 widget. Both 23 and 24 take three essential arguments:
31 is set to 52 by default, which means that the column or row doesn’t expand as the window resizes. If every column or row is given a weight of 39, then they all grow at the same rate. If one column has a weight of 39 and another a weight of 57, then the second column expands at twice the rate of the first. Adjust the previous script to better handle window resizing: 1 23 and 24 are placed in the body of the outer 45 loop. You could explicitly configure each column and row outside of the 45 loop, but that would require writing an additional six lines of code.On each iteration of the loop, the 42-th column and row are configured to have a weight of 39. This ensures that the row and column expand at the same rate whenever the window is resized. The 32 argument is set to 45 for each column and 67 for each row. This ensures that the 05 widget always displays its text without chopping off any characters, even if the window size is extremely small.The result is a grid layout that expands and contracts smoothly as the window is resized: Try it yourself to get a feel for how it works! Play around with the 31 and 32 parameters to see how they affect the grid.By default, widgets are centered in their grid cells. For example, the following code creates two 05 widgets and places them in a grid with one column and two rows: 2Each grid cell is 51 pixels wide and 06 pixels tall. The labels are placed in the center of each cell, as you can see in the following figure:You can change the location of each label inside of the grid cell using the 53 parameter, which accepts a string containing one or more of the following letters:
The letters 54, 58, 56, and 60 come from the cardinal directions north, south, east, and west. Setting 53 to 54 on both labels in the previous code positions each label at the top-center of its grid cell: 3Here’s the output: You can combine multiple letters in a single string to position each label in the corner of its grid cell: 4In this example, the 53 parameter of 72 is set to 70, which places the label at the top-right corner of its grid cell. 75 is positioned in the bottom-left corner by passing 72 to 53. Here’s what that looks like in the window:When a widget is positioned with 53, the size of the widget itself is just big enough to contain any text and other contents inside of it. It won’t fill the entire grid cell. In order to fill the grid, you can specify 75 to force the widget to fill the cell in the vertical direction, or 76 to fill the cell in the horizontal direction. To fill the entire cell, set 53 to 78. The following example illustrates each of these options: 5Here’s what the output looks like: What the above example illustrates is that the 98 geometry manager’s 53 parameter can be used to achieve the same effects as the 10 geometry manager’s 21 parameter. The correspondence between the 53 and 21 parameters is summarized in the following table: 98 10 87 43 89 42 91 92 98 is a powerful geometry manager. It’s often easier to understand than 10 and is much more flexible than 97. When you’re creating new Tkinter applications, you should consider using 98 as your primary geometry manager.Note: 98 offers much more flexibility than you’ve seen here. For example, you can configure cells to span multiple rows and columns. For more information, check out the Grid Geometry Manager section of the TkDocs tutorial.Now that you’ve got the fundamentals of geometry managers down for the Python GUI framework Tkinter, the next step is to assign actions to buttons to bring your applications to life. Remove adsCheck Your UnderstandingExpand the code block below for an exercise to check your understanding: Exercise: Create an address entry formShow/Hide Below is an image of an address entry form made with Tkinter: Write a complete script that re-creates the window. You may use any geometry manager you like. You can expand the code block below to see a solution: Solution: Create an address entry formShow/Hide There are many different ways to solve this exercise. If your solution generates a window identical to the one in the exercise statement, then congratulations! You’ve successfully solved the exercise! Below, you can look at two solutions that use the 98 geometry manager.One solution creates a 05 and 17 widget with the desired settings for each field: 6There’s nothing wrong with this solution. It’s a bit long, but everything is very explicit. If you want to change something, then it’s clear to see exactly where to do so. That said, the solution can be considerably shortened by recognizing that each 17 has the same width, and that all you need for each 05 is the text: 7In this solution, a is used to store the strings for each label in the form. They’re stored in the order that each form field should appear. Then, 03 gets both the index and string from each value in the 04 list.When you’re ready, you can move on to the next section. Making Your Applications InteractiveBy now, you have a pretty good idea of how to create a window with Tkinter, add some widgets, and control the application layout. That’s great, but applications shouldn’t just look good—they actually need to do something! In this section, you’ll learn how to bring your applications to life by performing actions whenever certain events occur. Using Events and Event HandlersWhen you create a Tkinter application, you must call 11 to start the event loop. During the event loop, your application checks if an event has occurred. If so, then it’ll execute some code in response.The event loop is provided for you with Tkinter, so you don’t have to write any code that checks for events yourself. However, you do have to write the code that will be executed in response to an event. In Tkinter, you write functions called event handlers for the events that you use in your application. Note: An event is any action that occurs during the event loop that might trigger some behavior in the application, such as when a key or mouse button is pressed. When an event occurs, an event object is emitted, which means that an instance of a class representing the event is created. You don’t need to worry about instantiating these classes yourself. Tkinter will create instances of event classes for you automatically. You’ll write your own event loop in order to better understand how Tkinter’s event loop works. That way, you can see how Tkinter’s event loop fits into your application, and which parts you need to write yourself. Assume there’s a list called 06 that contains event objects. A new event object is automatically appended to 06 every time an event occurs in your program. You don’t need to implement this updating mechanism. It just automatically happens for you in this conceptual example. Using an infinite loop, you can continually check if there are any event objects in 06: 8Right now, the event loop that you’ve created doesn’t do anything with 09. Let’s change that. Suppose your application needs to respond to keypresses. You need to check that 09 was generated by a user pressing a key on their keyboard, and if so, pass 09 to an event handler function for keypresses.Assume that 09 has a 13 attribute set to the string 14 if the event is a keypress event object, and a 15 attribute containing the character of the key that was pressed. Create a new 16 function and update your event loop code: 9When you call 11, something like the above loop is run for you. This method takes care of two parts of the loop for you:
Update your event loop to use 11 instead of your own event loop: 0 19 takes care of a lot for you, but there’s something missing from the above code. How does Tkinter know when to use 16? Tkinter widgets have a method called 21 for just this purpose.Remove adsUsing import tkinter as tk window = tk.Tk() label = tk.Label(text="Python rocks!") label.pack() window.mainloop() 21To call an event handler whenever an event occurs on a widget, use 21. The event handler is said to be bound to the event because it’s called every time the event occurs. You’ll continue with the keypress example from the previous section and use 21 to bind 16 to the keypress event: 1Here, the 16 event handler is bound to a 27 event using 28. Whenever a key is pressed while the application is running, your program will print the character of the key pressed.Note: The output of the above program is not printed in the Tkinter application window. It’s printed to the . If you run the program in IDLE, then you’ll see the output in the interactive window. If you run the program from a terminal, then you should see the output in your terminal. 21 always takes at least two arguments:
The event handler is bound to the widget on which 21 is called. When the event handler is called, the event object is passed to the event handler function.In the example above, the event handler is bound to the window itself, but you can bind an event handler to any widget in your application. For example, you can bind an event handler to a 16 widget that will perform some action whenever the button is pressed: 2In this example, the 34 event on the 35 widget is bound to the 36 event handler. The 34 event occurs whenever the left mouse button is pressed while the mouse is over the widget. There are other events for mouse button clicks, including 38 for the middle mouse button and 39 for the right mouse button.Note: For a list of commonly used events, see the Event types section of the Tkinter 8.5 reference. You can bind any event handler to any kind of widget with 21, but there’s a more straightforward way to bind event handlers to button clicks using the 16 widget’s 42 attribute.Using import tkinter as tk window = tk.Tk() label = tk.Label(text="Python rocks!") label.pack() window.mainloop() 42Every 16 widget has a 42 attribute that you can assign to a function. Whenever the button is pressed, the function is executed.Take a look at an example. First, you’ll create a window with a 05 widget that holds a numeric value. You’ll put buttons on the left and right side of the label. The left button will be used to decrease the value in the 05, and the right one will increase the value. Here’s the code for the window: 3The window looks like this: With the app layout defined, you can bring it to life by giving the buttons some commands. Start with the left button. When this button is pressed, it should decrease the value in the label by one. In order to do this, you first need to get answers to two questions:
05 widgets don’t have 70 like 17 and 18 widgets do. However, you can retrieve the text from the label by accessing the 34 attribute with a dictionary-style subscript notation: 4Now that you know how to get and set a label’s text, write an 55 function that increases the value in 56 by one: 5 55 gets the text from 56 and converts it to an integer with 59. Then, it increases this value by one and sets the label’s 34 attribute to this new value.You’ll also need 61 to decrease the value in 62 by one: 6Put 55 and 61 in your code just after the 65 statement.To connect the buttons to the functions, assign the function to the button’s 42 attribute. You can do this when you instantiate the buttons. For example, update the two lines that instantiate the buttons to the following: 7That’s all you need to do to bind the buttons to 55 and 61 and make the program functional. Try saving your changes and running the application! Click the buttons to increase and decrease the value in the center of the window:Here’s the full application code for your reference: Counter Application Full Source CodeShow/Hide 8This app isn’t particularly useful, but the skills you learned here apply to every app you’ll make:
In the next two sections, you’ll build more useful apps. First, you’ll build a temperature converter that converts a temperature value from Fahrenheit to Celsius. After that, you’ll build a text editor that can open, edit, and save text files! Check Your UnderstandingExpand the code block below for an exercise to check your understanding: Exercise: Simulate rolling a six-sided dieShow/Hide Write a program that simulates rolling a six-sided die. There should be one button with the text 69. When the user clicks the button, a random integer from 39 to 71 should be displayed.Hint: You can generate a random number using 72 in the module. If you’re not familiar with the 73 module, then check out Generating Random Data in Python (Guide) for more information.The application window should look something like this: Try this exercise now. You can expand the code block below to see a solution: Solution: Simulate rolling a six-sided dieShow/Hide Here’s one possible solution: 9Keep in mind that your code may look different. When you’re ready, you can move on to the next section. Building a Temperature Converter (Example App)In this section, you’ll build a temperature converter application that allows the user to input temperature in degrees Fahrenheit and push a button to convert that temperature to degrees Celsius. You’ll walk through the code step by step. You can also find the full source code at the end of this section for your reference. Note: To get the most out of this section, follow along in a Python shell. Before you start coding, you’ll first design the app. You need three elements:
You can arrange these in a grid with a single row and one column for each widget. That gets you a minimally working application, but it isn’t very user-friendly. Everything needs to have labels. You’ll put a label directly to the right of the 76 widget containing the Fahrenheit symbol (℉) so that the user knows that the value 76 should be in degrees Fahrenheit. To do this, set the label text to 85, which uses Python’s named Unicode character support to display the Fahrenheit symbol.You can give 80 a little flair by setting its text to the value 87, which displays a black arrow pointing to the right. You’ll also make sure that 78 always has the Celsius symbol (℃) following the label text 89 to indicate that the result is in degrees Celsius. Here’s what the final window will look like:Now that you know what widgets you need and what the window is going to look like, you can start coding it up! First, import 20 and create a new window: 0 91 sets the title of an existing window, while 92 with both arguments set to 93 makes the window have a fixed size. When you finally run this application, the window will have the text Temperature Converter in its title bar. Next, create the 76 widget with a label called 95 and assign both to a 19 widget called 97: 1The user will enter the Fahrenheit value in 76, and 95 is used to label 76 with the Fahrenheit symbol. The 97 container groups 76 and 95 together.You want 95 to be placed directly to the right of 76. You can lay them out in 97 using the 98 geometry manager with one row and two columns: 2You’ve set the 53 parameter to 56 for 76 so that it always sticks to the rightmost edge of its grid cell. You also set 53 to 60 for 95 to keep it stuck to the leftmost edge of its grid cell. This ensures that 95 is always located immediately to the right of 76.Now, make the 80 and the 78 for converting the temperature entered into 76 and displaying the results: 3Like 97, both 80 and 78 are assigned to 03. Together, these three widgets make up the three cells in the main application grid. Use 98 to go ahead and lay them out now: 4Finally, run the application: 5That looks great! But the button doesn’t do anything just yet. At the top of your script file, just below the 65 line, add a function called 25: 6This function reads the value from 76, converts it from Fahrenheit to Celsius, and then displays the result in 78.Now go down to the line where you define 80 and set its 42 parameter to 30: 7That’s it! You’ve created a fully functional temperature converter app in just twenty-six lines of code! Pretty cool, right? You can expand the code block below to see the full script: Temperature Converter Full Source CodeShow/Hide Here’s the full script for your reference: 8It’s time to kick things up a notch! Read on to learn how to build a text editor. Building a Text Editor (Example App)In this section, you’ll build a text editor application that can create, open, edit, and save text files. There are three essential elements in the application:
The three widgets will be arranged so that the two buttons are on the left-hand side of the window, and the text box is on the right-hand side. The whole window should have a minimum height of 800 pixels, and 36 should have a minimum width of 800 pixels. The whole layout should be responsive so that if the window is resized, then 36 is resized as well. The width of the frame holding the buttons should not change, however.Here’s a sketch of how the window will look: You can achieve the desired layout using the 98 geometry manager. The layout contains a single row and two columns:
To set the minimum sizes for the window and 36, you can set the 32 parameters of the window methods 24 and 23 to 44. To handle resizing, you can set the 31 parameters of these methods to 39.In order to get both buttons into the same column, you’ll need to create a 19 widget called 48. According to the sketch, the two buttons should be stacked vertically inside of this frame, with 32 on top. You can do that with either the 98 or 10 geometry manager. For now, you’ll stick with 98 since it’s a little easier to work with.Now that you have a plan, you can start coding the application. The first step is to create all of the widgets you need: 9Here’s a breakdown of this code:
Take a look at line 6 more closely. The 32 parameter of 24 is set to 44, and 31 is set to 39: 0The first argument is 52, which sets the height of the first row to 44 pixels and makes sure that the height of the row grows proportionally to the height of the window. There’s only one row in the application layout, so these settings apply to the entire window.Let’s also take a closer look at line 7. Here, you use 23 to set the 49 and 31 attributes of the column with index 39 to 44 and 39, respectively: 1Remember, row and column indices are zero-based, so these settings apply only to the second column. By configuring just the second column, the text box will expand and contract naturally when the window is resized, while the column containing the buttons will remain at a fixed width. Now you can work on the application layout. First, assign the two buttons to the 48 frame using the 98 geometry manager: 2These two lines of code create a grid with two rows and one column in the 48 frame since both 32 and 34 have their 04 attribute set to 48. 32 is put in the first row and 34 in the second row so that 32 appears above 34 in the layout, just you planned in your sketch.Both 32 and 34 have their 53 attributes set to 76, which forces the buttons to expand horizontally in both directions and fill the entire frame. This ensures that both buttons are the same size.You place five pixels of padding around each button by setting the 12 and 13 parameters to 61. Only 32 has vertical padding. Since it’s on top, the vertical padding offsets the button down from the top of the window a bit and makes sure that there’s a small gap between it and 34.Now that 48 is laid out and ready to go, you can set up the grid layout for the rest of the window: 3These two lines of code create a grid with one row and two columns for 03. You place 48 in the first column and 36 in the second column so that 48 appears to the left of 36 in the window layout.The 53 parameter for 48 is set to 75, which forces the whole frame to expand vertically and fill the entire height of its column. 36 fills its entire grid cell because you set its 53 parameter to 78, which forces it to expand in every direction.Now that the application layout is complete, add 11 to the bottom of the program and save and run the file: 4The following window is displayed: That looks great! But it doesn’t do anything just yet, so you need to start writing the commands for the buttons. 32 needs to show a file open dialog and allow the user to select a file. It then needs to open that file and set the text of 36 to the contents of the file. Here’s an 03 function that does just this: 5Here’s a breakdown of this function:
Now you can update the program so that 32 calls 03 whenever it’s clicked. There are a few things that you need to do to update the program. First, import 04 from 05 by adding the following import to the top of your program: 6Next, set the 42 attribute of 23 to 24: 7Save the file and run it to check that everything is working. Then try opening a text file! With 32 working, it’s time to work on the function for 34. This needs to open a save file dialog box so that the user can choose where they would like to save the file. You’ll use the 27 dialog in the 05 module for this. This function also needs to extract the text currently in 36 and write this to a file at the selected location. Here’s a function that does just this: 8Here’s how this code works:
Now you can update the program so that 34 calls 39 when it’s clicked. Again, there are a few things you need to do in order to update the program. First, import 27 from 05 by updating the import at the top of your script, like so: 9Finally, set the 42 attribute of 34 to 44: 00Save the file and run it. You’ve now got a minimal yet fully functional text editor! You can expand the code block below to see the full script: Text Editor Application Full Source CodeShow/Hide Here’s the full script for your reference: 01You’ve now built two GUI applications in Python and applied many of the skills that you’ve learned throughout this tutorial. That’s no small achievement, so take some time to feel good about what you’ve done. You’re now ready to tackle some applications on your own! ConclusionIn this tutorial, you learned how to get started with Python GUI programming. Tkinter is a compelling choice for a Python GUI framework because it’s built into the Python standard library, and it’s relatively painless to make applications with this framework. Throughout this tutorial, you’ve learned several important Tkinter concepts:
Now that you’ve mastered the foundations of Python GUI programming with Tkinter, the next step is to build some of your own applications. What will you create? Share your fun projects down in the comments below! Additional ResourcesIn this tutorial, you touched on just the foundations of creating Python GUI applications with Tkinter. There are a number of additional topics that aren’t covered here. In this section, you’ll find some of the best resources available to help you continue on your journey. Tkinter References Here are some official resources to check out:
Additional Widgets In this tutorial, you learned about the 05, 16, 17, 18, and 19 widgets. There are several other widgets in Tkinter, all of which are essential for building real-world applications. Here are some resources to continue learning about widgets:
Application Distribution Once you’ve created an application with Tkinter, you probably want to distribute it to your colleagues and friends. Here are some tutorials to get you going with that process:
Other GUI Frameworks Tkinter isn’t your only choice for a Python GUI framework. If Tkinter doesn’t meet the needs of your project, then here are some other frameworks to consider:
Take the Quiz: Test your knowledge with our interactive “Python GUI Programming With Tkinter” quiz. Upon completion you will receive a score so you can track your learning progress over time: Take the Quiz » Mark as Completed 🐍 Python Tricks 💌 Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team. Send Me Python Tricks » About David Amos David is a writer, programmer, and mathematician passionate about exploring mathematics through code. » More about DavidEach tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are: Aldren Bartosz Geir Arne Jaya Joanna Kate Master Real-World Python Skills With Unlimited Access to Real Python Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas: Level Up Your Python Skills » Master Real-World Python Skills Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas: Level Up Your Python Skills » What Do You Think? Rate this article: Tweet Share Share EmailWhat’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know. Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students. and get answers to common questions in our support portal. Apa itu Python GUI?Tkinter adalah graphic user interface (GUI) standar python digunakan untuk membuat tampilan aplikasi dengan komponen-komponen yang ada di modul tkinter seperti Button, Textbox, Label, Frame, Window yang mana sangat mendukung dalam penciptaan aplikasi GUI .
Apakah Python bisa membuat aplikasi desktop?Python adalah bahasa pemrograman multi-platform yang bersifat free dan open-source, dan dapat digunakan untuk mengembangkan aplikasi aplikasi desktop maupun web. Python memiliki pustaka standar (Python Standard Library) yang sangat lengkap sehingga dapat memenuhi berbagai macam permasalahan-permasalahan riil di dalam ...
Aplikasi apa yang bisa dibangun dengan Python?Sebagai bahasa pemrograman favorit, Python memiliki banyak kegunaan. Bahasa pemrograman ini digunakan untuk berbagai kepentingan, mulai dari pembuatan game offline dan online, maintenance website, machine learning, sampai aplikasi media sosial.
Apakah bisa membuat aplikasi Android dengan Python?Anda beruntung, bahasa Python telah bisa digunakan untuk membuat aplikasi Android, iOS atau framework lainnya. Paket yang digunakan adalah Kivy.
|