Create a GUI app with Python's Tkinter

I decided to make a GUI application with Python, and it was quick to use Tkinter, so this is a memorandum for the next use.

Template

import Tkinter as Tk

class Application(Tk.Frame):
    def __init__(self, master=None):
        Tk.Frame.__init__(self, master)
        self.pack()

root = Tk.Tk()
app = Application(master=root)
app.mainloop()

Various widgets will be attached here.

Widget[^1]

name role
Button button
Canvas Paste and draw images
Checkbutton Check button
Entry One-line text area. Multiple lines are Text
Frame A frame that holds other widgets together
Label label. Images can also be displayed
Listbox list box
Menu Creating a menu bar
Message Multi-line label
OptionMenu combo box
Radiobutton Radio buttons
Scale slider
Scrollbar scroll bar
Text Multi-line text area
Toplevel For making pop-up windows etc.

[^ 1]: Not all are covered

Widget placement

Use one of the pack, place, and grid methods to place the widget. pack arranges widgets in one column or one line. place specifies the location of each widget and places it. grid arranges widgets on 2D coordinates (it looks like Excel graph paper). After that, we basically use grid.

    def __init__(self, master=None):
        #abridgement
        self.create_widgets()

    def create_widgets(self):
        self.label = Tk.Label(self, text=u'Input file')
        self.entry = Tk.Entry(self)
        self.button = Tk.Button(self, text=u'open')
        self.check = Tk.Checkbutton(self, text=u'Limited extension to txt')
        self.text = Tk.Text(self)

        self.label.grid(column=0, row=0)
        self.entry.grid(column=1, row=0)
        self.button.grid(column=2, row=0)
        self.check.grid(column=0, row=1)
        self.text.grid(column=0, columnspan=3, row=2)

Support for placement adjustment and expansion / contraction

First, set expand, fill, and anchor to make the parent frame compatible with expansion and contraction. The position of Tk.XX that appears with anchor and sticky described later can be specified by north, south, east and west (NSEW).

    def __init__(self, master=None):
        Tk.Frame.__init__(self, master)
        self.pack(expand=1, fill=Tk.BOTH, anchor=Tk.NW)
        self.create_widgets()

Then, when arranging each widget with grid, specify where to expand and contract with sticky. Another important thing is that when you place a widget with grid, you need to specify which row / column expands and contracts at what ratio with column configure and row configure. By default, the weight parameter is 0 (does not stretch), so simply set the weight of the row / column you want to stretch to 1. In the following example, only the second line with Text corresponds to the expansion and contraction of the first column with Entry that is supposed to contain the selected file name.

        self.label.grid(column=0, row=0, sticky=Tk.W)
        self.entry.grid(column=1, row=0, sticky=Tk.EW)
        self.button.grid(column=2, row=0, sticky=Tk.E)
        self.check.grid(column=0, columnspan=2, row=1, sticky=Tk.W)
        self.text.grid(column=0, columnspan=3, row=2, sticky=Tk.NSEW)

        self.columnconfigure(1, weight=1)
        self.rowconfigure(2, weight=1)

Get the contents of Entry and the check status of Checkbutton

The contents of Entry and the check status of Checkbutton can be obtained by setting a variable in the (text) variable option.

        self.var_entry = Tk.StringVar()
        self.entry = Tk.Entry(self, textvariable=self.var_entry)
        self.var_check = Tk.BooleanVar()
        self.check = Tk.Checkbutton(self, text=u'Limited extension to txt',
                                    variable=self.var_check)

Use set () and get () to set and get the values of Tk.StringVar () and Tk.BooleanVar ().

Action when pressing a button

The method to be executed when the button is pressed is specified by the command option.

    def create_widgets(self):
        self.var_entry = Tk.StringVar()
        self.entry = Tk.Entry(self, textvariable=self.var_entry)
        self.button = Tk.Button(self, text=u'open', command=self.button_pushed)

    def button_pushed(self):
        self.var_entry.set(u'The button was pressed.')

File dialog

To open the file dialog, import tkFileDialog and use askopenfilename. You can specify the file types by using the filetypes option. In addition, tkFileDialog includes askopenfile, askopenfiles, askopenfilenames, asksaveasfile, asksaveasfilename, askdirectory, etc.

import tkFileDialog as tkFD

    def button_pushed(self):
        ft = [('text files', '.txt')] if self.var_check.get() else []
        self.var_entry.set(tkFD.askopenfilename(filetypes=ft))

Actions according to changes in variables

To monitor a variable and call a method when it changes, use the trace method.

    def create_widgets(self):
        self.var_entry = Tk.StringVar()
        self.var_entry.trace('w', self.entry_changed)

    def entry_changed(self, *args):
        if os.path.exists(self.var_entry.get()):
            self.text.delete('1.0', Tk.END)
            self.text.insert('1.0', open(self.var_entry.get()).read())

entry_changed is called when the value of var_entry is rewritten. First, erase all the contents of Text, and then display the contents of the file.

scroll bar

You can add a scroll bar to Text. [^ 2] There seems to be a widget called ScrolledText that has a vertical scroll bar from the beginning.

        self.text = Tk.Text(self, wrap=Tk.NONE)
        self.yscroll = Tk.Scrollbar(self, command=self.text.yview)
        self.xscroll = Tk.Scrollbar(self, command=self.text.xview,
                                    orient=Tk.HORIZONTAL)
        self.text['yscrollcommand'] = self.yscroll.set
        self.text['xscrollcommand'] = self.xscroll.set

        self.text.grid(column=0, columnspan=3, row=2, rowspan=2, sticky=Tk.NSEW)
        self.yscroll.grid(column=2, row=2, sticky=Tk.NS + Tk.E)
        self.xscroll.grid(column=0, columnspan=3, row=3, sticky=Tk.EW + Tk.S)

[^ 2]: The intersection of the scroll bars, I feel like I can do a little more

Paste image

It seems that Tkinter basically assumes gif. On the other hand, for example, savefig of matplotlib (pyplot) cannot save images as gif (isn't it?). So I converted it as follows and then pasted it, but is there a smarter way?

from PIL import Image
    def create_widgets(self):
        self.canvas = Tk.Canvas(self)
        self.canvas.grid(column=0, columnspan=3, row=4, sticky=Tk.NSEW)

    def set_image(self):
        img = Image.open('foo.png')
        img.save('_tmp.gif')
        self.image_data = Tk.PhotoImage(file='_tmp.gif')
        self.canvas.create_image(200, 100, image=self.image_data)

Standard output redirection

It's a copy and paste from stackoverflow. .. .. You can output the contents of standard output to Text etc.

import sys

    def __init__(self, master=None):
        Tk.Frame.__init__(self, master)
        self.pack(expand=1, fill=Tk.BOTH, anchor=Tk.NW)
        self.create_widgets()
        sys.stdout = self.StdoutRedirector(self.text)
        sys.stderr = self.StderrRedirector(self.text)

    class IORedirector(object):
        def __init__(self, text_area):
            self.text_area = text_area

    class StdoutRedirector(IORedirector):
        def write(self, st):
            self.text_area.insert(Tk.INSERT, st)

    class StderrRedirector(IORedirector):
        def write(self, st):
            self.text_area.insert(Tk.INSERT, st)

sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__

Python3 compatible

It seems that Tkinter has been renamed to tkinter and tkFileDialog has been renamed to filedialog.

Recommended Posts

Create a GUI app with Python's Tkinter
Create a native GUI app with Py2app and Tkinter
Create a GUI executable file created with tkinter
Try to dynamically create a Checkbutton with Python's Tkinter
Create a python GUI using tkinter
Easy GUI app with Tkinter Text
Create a simple GUI app in Python
Create a simple web app with flask
You can easily create a GUI with Python
Create a matrix with PythonGUI (tkinter combo box)
How to create a multi-platform app with kivy
Create a Todo app with Django REST Framework + Angular
Create a homepage with django
Create a Todo app with the Django REST framework
Create Image Viewer with Tkinter
Create a Todo app with Django ③ Create a task list page
Create a heatmap with pyqtgraph
Let's make a Mac app with Tkinter and py2app
[Python] Create a Tkinter program distribution file with cx_Freeze
Create a directory with python
Create a Todo app with Django ⑤ Create a task editing function
[Python] Create a file & folder path specification screen with tkinter
Create a machine learning app with ABEJA Platform + LINE Bot
Create a life game that is manually updated with tkinter
[Learning record] Create a mysterious dungeon game with Pyhton's Tkinter
Creating a GUI as easily as possible with python [tkinter edition]
Create a Todo app with Django ① Build an environment with Docker
Let's make a GUI with python.
Create a virtual environment with Python!
Creating a simple app with flask
Create a poisson stepper with numpy.random
Draw a graph with PySimple GUI
Create a file uploader with Django
Create a Python function decorator with Class
Creating an image splitting app with Tkinter
Build a blockchain with Python ① Create a class
Create a dummy image with Python + PIL.
Play like a web app with ipywidgets
Make GUI apps super easy with tkinter
[Python] Create a virtual environment with Anaconda
Let's create a free group with Python
Daemonize a Python web app with Supervisor
Create a large text file with shellscript
Create a star system with Blender 2.80 script
Create a virtual environment with Python_Mac version
Create a VM with a YAML file (KVM)
Create a Python-GUI app in Docker (PySimpleGUI)
Create a word frequency counter with Python 3.4
Create your first app with Django startproject
Create a Connecting Nearest Neighbor with NetworkX
Create an English word app with python
Create a web service with Docker + Flask
Create a private repository with AWS CodeArtifact
Make a desktop app with Python with Electron
Create a car meter with raspberry pi
Create a devilish picture with Blender scripts
Create a matrix with PythonGUI (text box)
Create a graph with borders removed with matplotlib
Web App Development Practice: Create a Shift Creation Page with Django! (Introduction)
Create a Todo app with Django ④ Implement folder and task creation functions
Create an app that guesses students with python