{"id":8313,"date":"2026-04-24T12:00:00","date_gmt":"2026-04-24T12:00:00","guid":{"rendered":"https:\/\/www.askpython.com\/?p=8313"},"modified":"2026-09-29T16:40:52","modified_gmt":"2026-09-29T16:40:52","slug":"tkinter-gui-widgets","status":"publish","type":"post","link":"https:\/\/www.askpython.com\/python\/tkinter-gui-widgets","title":{"rendered":"Tkinter GUI Widgets"},"content":{"rendered":"<p>Tkinter is Python&#8217;s standard GUI library. It ships with every Python installation, requires no separate installation, and provides enough widgets to build real desktop applications. This guide walks through the most commonly used Tkinter widgets, with working examples you can run right away.<\/p>\n\n<p>Each widget handles a specific UI role &#8211; from displaying text to accepting user input. Once you know what each one does, combining them with layout managers like <code>pack()<\/code> and <code>grid()<\/code> lets you build complete interfaces.<\/p>\n\n\n<h2 class=\"wp-block-heading\">TLDR<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Label<\/strong> &#8211; displays read-only text or images<\/li>\n\n<li><strong>Button<\/strong> &#8211; triggers a function when clicked<\/li>\n\n<li><strong>Checkbutton<\/strong> &#8211; toggle for on\/off states with IntVar<\/li>\n\n<li><strong>Entry<\/strong> &#8211; single-line text input with StringVar<\/li>\n\n<li><strong>Scale<\/strong> &#8211; slider for numeric values within a range<\/li>\n\n<li><strong>Listbox<\/strong> &#8211; scrollable list for single or multiple selection<\/li>\n\n<li><strong>Radiobutton<\/strong> &#8211; mutually exclusive single-choice buttons<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Setting Up the Main Window<\/h2>\n\n\n<p>Every Tkinter application follows the same three-step pattern: import the library, create the root window, and start the event loop.<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\nimport tkinter as tk\n\n# Create the root window\nroot = tk.Tk()\nroot.title(&quot;My First GUI App&quot;)\nroot.geometry(&quot;400x300&quot;)  # Width x Height in pixels\n\n# Your widgets go here\nlabel = tk.Label(root, text=&quot;Hello, Tkinter!&quot;)\nlabel.pack()\n\n# Start the event loop\nroot.mainloop()\n\n<\/pre><\/div>\n\n<p><code>tk.Tk()<\/code> creates the main application window. <code>geometry()<\/code> sets its dimensions in pixels. <code>mainloop()<\/code> runs the event listener for clicks, keystrokes, and other user interactions &#8211; the program stays here until the window is closed. Everything between creating the window and calling <code>mainloop()<\/code> is where you assemble your interface.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Label &#8211; Display Text and Images<\/h2>\n\n\n<p>The <code>Label<\/code> widget displays read-only text or images. It is the simplest widget and appears throughout Tkinter applications for headings, descriptions, status messages, and image previews.<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\nimport tkinter as tk\n\nroot = tk.Tk()\nroot.title(&quot;Label Demo&quot;)\nroot.geometry(&quot;400x200&quot;)\n\n# Basic text label\ntitle_label = tk.Label(\n    root,\n    text=&quot;Welcome to Tkinter!&quot;,\n    font=(&quot;Arial&quot;, 18, &quot;bold&quot;),\n    fg=&quot;darkblue&quot;\n)\ntitle_label.pack(pady=10)\n\n# Label with wrapping and center alignment\ndescription = tk.Label(\n    root,\n    text=&quot;Labels display static text. They are read-only - &quot;\n         &quot;use Entry widgets for user input.&quot;,\n    font=(&quot;Arial&quot;, 10),\n    fg=&quot;gray&quot;,\n    wraplength=350,\n    justify=&quot;center&quot;\n)\ndescription.pack(pady=10)\n\n# Label with background color\nhighlight = tk.Label(\n    root,\n    text=&quot;Colored backgrounds are easy too!&quot;,\n    font=(&quot;Arial&quot;, 12, &quot;italic&quot;),\n    bg=&quot;lightyellow&quot;,\n    padx=20,\n    pady=10\n)\nhighlight.pack(pady=10)\n\nroot.mainloop()\n\n<\/pre><\/div>\n\n<p>Common Label parameters: <code>text<\/code> sets the displayed string, <code>font<\/code> controls typography, <code>fg<\/code> sets text color, <code>bg<\/code> sets background color, <code>wraplength<\/code> controls line width, and <code>justify<\/code> sets text alignment.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Button &#8211; Trigger Actions on Click<\/h2>\n\n\n<p>Buttons are interactive widgets that call a function when clicked. You pass the function reference to the <code>command<\/code> parameter &#8211; pass the function name without parentheses.<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\nimport tkinter as tk\n\ndef on_click():\n    label.config(text=&quot;Button was clicked!&quot;, fg=&quot;green&quot;)\n\ndef on_reset():\n    label.config(text=&quot;Press the button above&quot;, fg=&quot;black&quot;)\n\nroot = tk.Tk()\nroot.title(&quot;Button Demo&quot;)\nroot.geometry(&quot;400x200&quot;)\n\nlabel = tk.Label(root, text=&quot;Press the button below&quot;, font=(&quot;Arial&quot;, 14))\nlabel.pack(pady=30)\n\n# A regular button\nmy_button = tk.Button(\n    root,\n    text=&quot;Click Me!&quot;,\n    command=on_click,\n    font=(&quot;Arial&quot;, 12),\n    bg=&quot;cornflowerblue&quot;,\n    fg=&quot;white&quot;,\n    padx=20,\n    pady=5,\n    cursor=&quot;hand2&quot;\n)\nmy_button.pack(pady=10)\n\n# A reset button\nreset_button = tk.Button(\n    root,\n    text=&quot;Reset&quot;,\n    command=on_reset,\n    font=(&quot;Arial&quot;, 10),\n    bg=&quot;lightgray&quot;\n)\nreset_button.pack(pady=5)\n\nroot.mainloop()\n\n<\/pre><\/div>\n\n<p>When a button is clicked, Tkinter calls the function assigned to <code>command<\/code>. Both buttons above modify the same Label by calling different functions &#8211; demonstrating how multiple widgets interact through shared functions. The <code>cursor=\"hand2\"<\/code> parameter gives the button a hand cursor on hover.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Checkbutton &#8211; Toggle Boolean States<\/h2>\n\n\n<p>A <code>Checkbutton<\/code> is a two-state toggle &#8211; checked or unchecked. It pairs with an <code>IntVar<\/code> to store its state. When the user checks or unchecks it, the variable automatically updates to 1 or 0.<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\nimport tkinter as tk\n\ndef show_settings():\n    output = &#x5B;]\n    if python_check.get():\n        output.append(&quot;Python enabled&quot;)\n    if java_check.get():\n        output.append(&quot;Java enabled&quot;)\n    if cpp_check.get():\n        output.append(&quot;C++ enabled&quot;)\n    if not output:\n        output.append(&quot;No languages selected&quot;)\n    result_label.config(text=&quot;\\n&quot;.join(output))\n\nroot = tk.Tk()\nroot.title(&quot;Checkbutton Demo&quot;)\nroot.geometry(&quot;400x250&quot;)\n\nintro = tk.Label(root, text=&quot;Select your programming languages:&quot;,\n                 font=(&quot;Arial&quot;, 12, &quot;bold&quot;))\nintro.pack(pady=10)\n\n# IntVar stores 1 (checked) or 0 (unchecked)\npython_check = tk.IntVar()\njava_check = tk.IntVar()\ncpp_check = tk.IntVar()\n\ntk.Checkbutton(\n    root,\n    text=&quot;Python&quot;,\n    variable=python_check,\n    command=show_settings,\n    font=(&quot;Arial&quot;, 11)\n).pack(anchor=&quot;w&quot;, padx=100)\n\ntk.Checkbutton(\n    root,\n    text=&quot;Java&quot;,\n    variable=java_check,\n    command=show_settings,\n    font=(&quot;Arial&quot;, 11)\n).pack(anchor=&quot;w&quot;, padx=100)\n\ntk.Checkbutton(\n    root,\n    text=&quot;C++&quot;,\n    variable=cpp_check,\n    command=show_settings,\n    font=(&quot;Arial&quot;, 11)\n).pack(anchor=&quot;w&quot;, padx=100)\n\nresult_label = tk.Label(root, text=&quot;No languages selected&quot;,\n                        font=(&quot;Arial&quot;, 10), fg=&quot;green&quot;)\nresult_label.pack(pady=20)\n\nroot.mainloop()\n\n<\/pre><\/div>\n\n<p>Each <code>Checkbutton<\/code> gets its own <code>IntVar<\/code>. When you click a checkbox, Tkinter automatically sets that variable to 1 or 0. Set the initial state with <code>python_check.set(1)<\/code>. This widget suits settings panels, feature toggles, and multi-select scenarios.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Entry &#8211; Single-Line Text Input<\/h2>\n\n\n<p>The <code>Entry<\/code> widget accepts a single line of text input. It works with a <code>StringVar<\/code> to read and write its value. Use <code>.get()<\/code> to retrieve the current text and <code>.set()<\/code> to change it programmatically.<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n&lt;pre class=&quot;wp-block-syntaxhighlighter-code&quot;&gt;\nimport tkinter as tk\n\ndef submit():\n    name = name_var.get()\n    if name.strip():\n        greeting.config(text=f&quot;Hello, {name.strip()}! Welcome to Tkinter.&quot;)\n    else:\n        greeting.config(text=&quot;Please enter your name.&quot;)\n\ndef clear():\n    name_var.set(&quot;&quot;)\n    greeting.config(text=&quot;&quot;)\n\nroot = tk.Tk()\nroot.title(&quot;Entry Demo&quot;)\nroot.geometry(&quot;400x220&quot;)\n\ntk.Label(root, text=&quot;Enter your name:&quot;,\n         font=(&quot;Arial&quot;, 12, &quot;bold&quot;)).pack(pady=10)\n\n# StringVar to hold the entry text\nname_var = tk.StringVar()\n\nentry = tk.Entry(root, textvariable=name_var, font=(&quot;Arial&quot;, 12), width=30)\nentry.pack(pady=5)\n\n# Focus the cursor here automatically when the window opens\nentry.focus()\n\n# Bind the Enter key to submit\nentry.bind(&quot;&lt;Return&gt;&quot;, lambda e: submit())\n\nsubmit_btn = tk.Button(root, text=&quot;Submit&quot;, command=submit,\n                        font=(&quot;Arial&quot;, 11), bg=&quot;steelblue&quot;, fg=&quot;white&quot;)\nsubmit_btn.pack(pady=5)\n\nclear_btn = tk.Button(root, text=&quot;Clear&quot;, command=clear,\n                      font=(&quot;Arial&quot;, 11), bg=&quot;lightgray&quot;)\nclear_btn.pack(pady=5)\n\ngreeting = tk.Label(root, text=&quot;&quot;, font=(&quot;Arial&quot;, 13, &quot;italic&quot;), fg=&quot;navy&quot;)\ngreeting.pack(pady=15)\n\nroot.mainloop()\n&lt;\/pre&gt;\n<\/pre><\/div>\n\n<p><code>entry.bind(\"<Return>\", lambda e: submit())<\/code> binds the Enter key to the submit function, so pressing Enter triggers the same action as clicking the button. The <code>focus()<\/code> call ensures the text field is ready when the window opens.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Scale &#8211; Slider for Numerical Input<\/h2>\n\n\n<p>The <code>Scale<\/code> widget provides a draggable slider for selecting a numeric value within a range. It suits volume controls, color pickers, and any scenario where picking a value within a range is more intuitive than typing a number.<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\nimport tkinter as tk\n\ndef show_value(value):\n    result.config(text=f&quot;Selected value: {value}&quot;)\n\nroot = tk.Tk()\nroot.title(&quot;Scale Demo&quot;)\nroot.geometry(&quot;400x300&quot;)\n\ntk.Label(root, text=&quot;Adjust the volume:&quot;,\n         font=(&quot;Arial&quot;, 14, &quot;bold&quot;)).pack(pady=10)\n\n# IntVar to track the scale value\nvolume = tk.IntVar()\nvolume.set(50)  # Default value\n\n# A horizontal scale from 0 to 100\nscale = tk.Scale(\n    root,\n    from_=0,          # Minimum value\n    to=100,           # Maximum value\n    orient=&quot;horizontal&quot;,\n    variable=volume,\n    command=show_value,\n    length=300,\n    tickinterval=20,\n    showvalue=True\n)\nscale.pack(pady=20)\n\nresult = tk.Label(root, text=&quot;Selected value: 50&quot;,\n                  font=(&quot;Arial&quot;, 12), fg=&quot;darkgreen&quot;)\nresult.pack(pady=10)\n\n# Button to print the current value\ntk.Button(root, text=&quot;Confirm Volume&quot;,\n          command=lambda: print(f&quot;Volume set to: {volume.get()}&quot;),\n          font=(&quot;Arial&quot;, 11), bg=&quot;darkgreen&quot;, fg=&quot;white&quot;).pack(pady=5)\n\nroot.mainloop()\n\n<\/pre><\/div>\n\n<p>Key Scale parameters: <code>from_<\/code> and <code>to<\/code> define the range, <code>orient<\/code> controls horizontal or vertical layout, <code>tickinterval<\/code> adds tick marks at intervals, and <code>showvalue<\/code> displays the current numeric value above the slider. The <code>command<\/code> callback receives the current value as a string argument each time the slider moves.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Listbox &#8211; List Selection<\/h2>\n\n\n<p>The <code>Listbox<\/code> widget displays a scrollable list of items. It supports single or multiple selection, and you retrieve selected item(s) with <code>curselection()<\/code>.<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n&lt;pre class=&quot;wp-block-syntaxhighlighter-code&quot;&gt;\nimport tkinter as tk\n\ndef show_selection():\n    selection = languages_listbox.curselection()\n    if selection:\n        selected = languages_listbox.get(selection&#x5B;0])\n        result.config(text=f&quot;You selected: {selected}&quot;)\n    else:\n        result.config(text=&quot;No item selected&quot;)\n\nroot = tk.Tk()\nroot.title(&quot;Listbox Demo&quot;)\nroot.geometry(&quot;400x300&quot;)\n\ntk.Label(root, text=&quot;Choose a programming language:&quot;,\n         font=(&quot;Arial&quot;, 13, &quot;bold&quot;)).pack(pady=10)\n\n# Create and populate the listbox\nlanguages_listbox = tk.Listbox(root, font=(&quot;Arial&quot;, 12), height=8)\nlanguages = &#x5B;&quot;Python&quot;, &quot;Java&quot;, &quot;C++&quot;, &quot;JavaScript&quot;, &quot;Rust&quot;,\n             &quot;Go&quot;, &quot;TypeScript&quot;, &quot;Kotlin&quot;]\nfor lang in languages:\n    languages_listbox.insert(&quot;end&quot;, lang)\nlanguages_listbox.pack(pady=5)\n\n# Select the first item by default\nlanguages_listbox.select_set(0)\n\n# Bind double-click to selection\nlanguages_listbox.bind(&quot;&lt;Double-Button-1&gt;&quot;, lambda e: show_selection())\n\ntk.Button(root, text=&quot;Confirm Selection&quot;,\n          command=show_selection,\n          font=(&quot;Arial&quot;, 11), bg=&quot;purple&quot;, fg=&quot;white&quot;).pack(pady=5)\n\nresult = tk.Label(root, text=&quot;&quot;, font=(&quot;Arial&quot;, 11), fg=&quot;purple&quot;)\nresult.pack(pady=10)\n\nroot.mainloop()\n&lt;\/pre&gt;\n<\/pre><\/div>\n\n<p><code>curselection()<\/code> returns a tuple of selected indices. Use <code>listbox.get(index)<\/code> to retrieve the item at a given index. <code>insert(\"end\", item)<\/code> adds items to the end of the list. For multiple selection mode, set <code>selectmode=\"multiple\"<\/code> and iterate over <code>curselection()<\/code> to handle multiple indices.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Radiobutton &#8211; Mutually Exclusive Choices<\/h2>\n\n\n<p><code>Radiobutton<\/code> widgets belong to a group where only one can be selected at a time. They share an <code>IntVar<\/code>, and each button is associated with a different value. Selecting a new button automatically deselects the previous one.<\/p>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\nimport tkinter as tk\n\ndef show_choice():\n    result.config(text=f&quot;You chose: {choice.get()} (value: {choice.get()})&quot;)\n\nroot = tk.Tk()\nroot.title(&quot;Radiobutton Demo&quot;)\nroot.geometry(&quot;400x280&quot;)\n\ntk.Label(root, text=&quot;Select your experience level:&quot;,\n         font=(&quot;Arial&quot;, 13, &quot;bold&quot;)).pack(pady=10)\n\n# Single IntVar shared across all radio buttons\nchoice = tk.IntVar()\nchoice.set(1)  # Default selection\n\n# Radiobutton with integer value\ntk.Radiobutton(\n    root,\n    text=&quot;Beginner - I&#039;m just starting out&quot;,\n    variable=choice,\n    value=1,\n    command=show_choice,\n    font=(&quot;Arial&quot;, 11)\n).pack(anchor=&quot;w&quot;, padx=80, pady=3)\n\ntk.Radiobutton(\n    root,\n    text=&quot;Intermediate - I know the basics&quot;,\n    variable=choice,\n    value=2,\n    command=show_choice,\n    font=(&quot;Arial&quot;, 11)\n).pack(anchor=&quot;w&quot;, padx=80, pady=3)\n\ntk.Radiobutton(\n    root,\n    text=&quot;Advanced - I build complex applications&quot;,\n    variable=choice,\n    value=3,\n    command=show_choice,\n    font=(&quot;Arial&quot;, 11)\n).pack(anchor=&quot;w&quot;, padx=80, pady=3)\n\ntk.Radiobutton(\n    root,\n    text=&quot;Expert - I contribute to open source&quot;,\n    variable=choice,\n    value=4,\n    command=show_choice,\n    font=(&quot;Arial&quot;, 11)\n).pack(anchor=&quot;w&quot;, padx=80, pady=3)\n\nresult = tk.Label(root, text=&quot;You chose: 1 (value: 1)&quot;,\n                  font=(&quot;Arial&quot;, 12, &quot;italic&quot;), fg=&quot;darkred&quot;)\nresult.pack(pady=20)\n\nroot.mainloop()\n\n<\/pre><\/div>\n\n<p>All four <code>Radiobutton<\/code> widgets share the same <code>choice<\/code> variable. When one is selected, <code>choice.get()<\/code> returns that button&#8217;s assigned value. This mutual exclusivity makes radio buttons the right choice for single-option selections like experience level, payment method, or subscription tier.<\/p>\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Q: How do I run a Tkinter application?<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Save your Python code to a file with a .py extension and run it with python filename.py. The application launches in a native window. Tkinter applications require an active display environment to render GUI windows.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Q: What is the difference between pack() and grid()?<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>pack()<\/code> places widgets in a single direction &#8211; either top-to-bottom (default) or left-to-right. <code>grid()<\/code> places widgets in a table of rows and columns, giving fine control over precise layout. <code>place()<\/code> positions widgets at absolute pixel coordinates. Mix these layout managers within the same application as needed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Q: Can Tkinter display images?<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Yes. Use the <code>PhotoImage<\/code> class for GIF and PNG formats. For other image formats, use the PIL library with <code>ImageTk.PhotoImage<\/code>. Assign the image to a Label widget with <code>label.config(image=photo)<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Q: How do I handle multiple windows?<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create additional <code>tk.Toplevel()<\/code> windows. These are secondary windows that depend on the main window. When the main window closes, all <code>Toplevel<\/code> windows close as well.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tkinter provides a complete GUI toolkit out of the box. These seven widgets cover the foundations of most Tkinter applications. Combine them with layout managers to arrange them on screen, and you will be building functional desktop interfaces in short order.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Tkinter is Python&#8217;s standard GUI library. It ships with every Python installation, requires no separate installation, and provides enough widgets to build real desktop applications. This guide walks through the most commonly used Tkinter widgets, with working examples you can run right away. Each widget handles a specific UI role &#8211; from displaying text to [&hellip;]<\/p>\n","protected":false},"author":12,"featured_media":68131,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,92],"tags":[],"class_list":["post-8313","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python","category-tkinter"],"_links":{"self":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/8313","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/comments?post=8313"}],"version-history":[{"count":0,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/8313\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/media\/68131"}],"wp:attachment":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/media?parent=8313"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/categories?post=8313"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/tags?post=8313"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}