Skip to Content
Course content

385: Menus, Dialogs, and File Pickers in tkinter

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've been tinkering with a small utility to help me parse through system logs, but right now it's just a blank window. To make this actually usable, I can't expect the user to hardcode a file path in the script. I need a way to browse the filesystem, a way to trigger actions via a menu, and a way to pop up a quick question to the user. Let's build these pieces out together.

Getting the top bar to actually show up

First, I want a standard "File" menu. If I just create a Menu widget and place it, it'll probably just float there like a button, which isn't what we want. We want the system menu bar.

import tkinter as tk
from tkinter import Menu

root = tk.Tk()
root.geometry("400x300")

# I'll start by creating the main menu bar
menubar = Menu(root)

# Now I'll try to add a "File" option
file_menu = Menu(menubar, tearoff=0) 
file_menu.add_command(label="Exit", command=root.quit)

# I'll add the file_menu to the menubar using 'cascade'
menubar.add_cascade(label="File", menu=file_menu)

# Wait, I ran this and nothing happened. 
# Ah, I forgot to tell the root window to actually USE this menubar.
root.config(menu=menubar)

root.mainloop()

Notice that tearoff=0? If I leave that out, tkinter adds a weird dashed line at the top of the menu that lets the user "tear off" the menu into a separate window. It's a very 1990s feature that almost nobody wants in a modern app, so I always disable it immediately.

Hunting for the right file

Now, "Exit" is great, but I need a way to open a log file. I could try to build my own file browser, but that's a nightmare. I'll use the filedialog module. One thing to watch out for: filedialog is a submodule, so importing tkinter isn't enough; I have to import it explicitly.

from tkinter import filedialog

def open_file():
    # I want to restrict this to text files so I don't accidentally open a PDF
    file_path = filedialog.askopenfilename(
        title="Select a Log File",
        filetypes=(("Text files", "*.txt"), ("Log files", "*.log"), ("All files", "*.*"))
    )
    
    if file_path:
        print(f"User selected: {file_path}")
    else:
        print("User cancelled the picker.")

# Now I'll plug this into my existing menu
file_menu.add_command(label="Open...", command=open_file)

I noticed that if the user hits "Cancel," askopenfilename returns an empty string. I have to handle that with an if file_path: check, otherwise my program might try to read a non-existent file and crash.

Asking the user for input

Finally, let's say I want to filter the log file by a specific keyword. I don't want to build a whole new search page; I just need a quick prompt. For this, simpledialog is the way to go.

from tkinter import simpledialog

def search_log():
    # This pops up a small dialog with an input field
    keyword = simpledialog.askstring("Search", "What keyword are you looking for?")
    
    if keyword:
        print(f"Searching for: {keyword}")
    else:
        print("No keyword entered.")

# Adding this to a new "Edit" menu
edit_menu = Menu(menubar, tearoff=0)
edit_menu.add_command(label="Search Keyword", command=search_log)
menubar.add_cascade(label="Edit", menu=edit_menu)

It's interesting how tkinter splits these into different modules (filedialog, simpledialog, messagebox). It keeps the core tkinter namespace cleaner, but it means you'll spend a few minutes wondering why tk.filedialog is throwing an AttributeError until you realize you need the separate import.




📋 Practical Task

Exercise: The Custom Configurator Tool

Build a small application called "App Configurator" that implements the following requirements:

  • Menu Bar: Create a menu bar with two menus: "Settings" and "System".
  • The File Picker: Under "Settings", add an "Open Config File" option. When clicked, it should open a file picker (filtered for .ini or .conf files). Once a file is selected, display the path to that file in a tkinter.Label on the main window.
  • The User Dialog: Under "System", add a "Set User Name" option. When clicked, it should use a simpledialog to ask the user for their name. Display the entered name in a second Label on the main window.
  • The Exit: Ensure there is a way to close the application via the menu.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.