Tkinter GUI Programming by Example Learn to create modern GUIs using Tkinter by building real-world projects in Python David Love BIRMINGHAM - MUMBAI Tkinter GUI Programming by Example Copyright © 2018 Packt Publishing All rights reserved No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews Every effort has been made in the preparation of this book to ensure the accuracy of the information presented However, the information contained in this book is sold without warranty, either express or implied Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals However, Packt Publishing cannot guarantee the accuracy of this information Commissioning Editor: Aaron Lazar Acquisition Editor: Denim Pinto Content Development Editor: Anugraha Arunagiri Technical Editor: Subhalaxmi Nadar Copy Editor: Safis Editing Project Coordinator: Ulhas Kambali Proofreader: Safis Editing Indexer: Aishwarya Gangawane Graphics: Tania Dutta Production Coordinator: Arvindkumar Gupta First published: April 2018 Production reference: 1240418 Published by Packt Publishing Ltd Livery Place 35 Livery Street Birmingham B3 2PB, UK ISBN 978-1-78862-748-1 www.packtpub.com mapt.io Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career For more information, please visit our website Why subscribe? Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals Improve your learning with Skill Plans built especially for you Get a free eBook or video every month Mapt is fully searchable Copy and paste, print, and bookmark content PacktPub.com Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy Get in touch with us at service@packtpub.com for more details At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks Contributors About the author David Love is a web developer from Kent, England He has worked on a multitude of different systems over his career Programming languages in his arsenal include Python, PHP, and JavaScript He is well-trained in Linux server management and its relevant technologies, including MySQL, PostgreSQL, NGINX, and supervisor David has written an e-book called Tkinter By Example, which is available for free under a Creative Commons licenses and maintains an ever-growing blog post named The Tkinter Cookbook, full of small examples on how to perform some specific tasks font_family = self.font_list.get(self.font_list.curselection()[0]) yaml_file_contents = f"family: {font_family}\n" \ + f"size: {self.size_input.get()}" with open(self.master.font_scheme_path, 'w') as file: file.write(yaml_file_contents) self.master.update_font() ### colorchooser.py def save(self): yaml_file_contents = + + + f"background: '{self.chosen_background_color.get()}'\n" \ f"foreground: '{self.chosen_foreground_color.get()}'\n" \ f"text_background: '{self.chosen_text_background_color.get()}'\n" \ f"text_foreground: '{self.chosen_text_foreground_color.get()}'\n" with open(self.master.default_scheme_path, "w") as yaml_file: yaml_file.write(yaml_file_contents) With that, we are ready to package! We can now begin the steps necessary for packaging up our application Preparing to package with setup.py When packaging an application, a special file called setup.py is required This file will be read by the packaging tool and used to determine things such as which libraries to include, and which files should be run when the user executes the application Create a file named setup.py in your main text editor folder (which I have named tkedit) and add the following content: #!/usr/bin/env python3 from distutils.core import setup setup( name='tkedit', version='0.1', description='This is a python text editor with syntax highlighting', author='David Love', py_modules = [ "colorchooser", "findwindow", "fontchooser", "highlighter", "linenumbers", "textarea", "texteditor", ], install_requires = [ "PyYAML", ], entry_points = { "console_scripts": ["tkedit = texteditor:main"] } ) To get our application building, we need to use a module designed to that Python comes with pip, which does a great job at handling this Pip will use a module called distutils to prepare a package and we will need the setup function from its core module to this After importing the setup function, we just need to call it, passing quite a few keyword arguments These arguments represent the following: : The application's name version: The application's version description: A short description of the application author: The author's name py_modules: The modules (Python files) which will be extracted from the current project install_requires: Any external libraries which need to be installed by pip to make the application usable entry_points: The commands which can be run once the package is installed, and what Python function they correspond to name For this example, the entry_points argument defines a command tkedit which should run the main function from the texteditor module We don't have this function yet, so we need to quickly go back to our texteditor.py file and add it Note that this function will need to be defined outside of the TextEditor class, just before the if name == " main " block: def main(): mw = MainWindow() mw.mainloop() With the setup file created, we are now one step closer to distributing our application Let's now have a look at exactly how this will be done Installing our text editor How to build and install a Python application is dependent on the OS which is being used to package it Typically, each operating system only allows the application to be built for the same platform, meaning only Windows can create Windows exe files, and so on Pip, however, is able to run on all platforms, so can be used as a way of packaging once for any system For a user who will already have Python installed, we can distribute our applications as pip packages This will work on all platforms, but requires the user to have the correct version of Python and pip already installed, and also to be able to use the command line Cross-platform using Pip Our application is already set up to be distributed with pip You can test this out yourself by opening a terminal window inside the root folder for your text editor and using the following commands: $ python3 -m venv build-env $ source build-env/bin/activate $ pip install Provided that you are in the same directory as your setup.py file, pip should be able to parse this and install your text editor to your new virtual environment You should now be able to run the tkedit command and be shown your text editor application! If you wish to install the module globally, skip the creation of the virtual environment and just run sudo pip install This should install your text editor on your system so that it can be run from anywhere Whilst simple, the pip being used is a barrier to entry for any users who may not have Python installed or who are put off by using the command line Let's have a look at how we can package our application into an executable file for each OS Windows To package our text editor for Windows, we will need to use a module known as cx_freeze This module is installed using pip via pip install cx_freeze To tell cx_freeze about our application, we will need to adjust our setup.py file: from cx_Freeze import setup, Executable import sys base = 'Win32GUI' if sys.platform=='win32' else None import os PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os. file )) os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6') os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6') options = { 'build_exe': { 'include_files':[ os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'), os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'), ], }, } executables = [ Executable('tkedit.py', base=base) ] setup(name='tkedit', version = '1.0', description = 'A tkinter text editor', options = options, executables = executables) Instead of the setup function from distutils, we will be using the cx_freeze version We import the sys module and use it to set a special variable as if we are on a 32 bit operating system Windows needs to know the location of the library of tcl and tk (which power Tkinter) To correctly form the paths to these files, we get the path to our Python installation, then join the necessary folders to it These are set as environment variables, since cx_freeze will need to reference them during the build process When building the exe, file, cx_freeze will also need to find the dll files for tk and tcl We create the paths to them inside a dictionary named options, under the build_exe and include_files keys With these libraries located, we now need to create an executable We create an instance of the Executable class from cx_freeze and pass it a filename of tkedit.py, as well as the base which we defined earlier Once that is taken care of, we call the setup function as before, passing it our new options and executables variables Before we can run this, we need to create tkedit.py Luckily, this is a very small file: from texteditor import main main() Much like we had to allude to with Pip's version of the setup.py file, we need to call a function when the executable is run This function will be the main function from our texteditor.py file In this file, we just import the function and run it This allows cx_freeze to just run the tkedit.py file instead of parsing out the main function from our texteditor.py file With these two files taken care of, we can now build our application for windows Open a command line in your root folder and run the following command: python3 setup.py build If everything has gone smoothly, you should see a lot of information about copying libraries, and then find that a folder named build has been added to your project Open up explorer and navigate to this folder You should see another folder beginning with exe-win32 Head to that folder and you should see tkedit.exe sitting there Run this file and check out your text editor! Linux Since Linux users will likely be familiar with command-line tools and most distributions will come with Python and pip installed already Using pip is the recommended method for distributing your Python applications If you not wish to use pip, there are many alternatives available, depending on the particular distribution the user is running For steps to create an AppImage binary, check out the official AppImages GitHub repository There's a sample Python application available here: https://github.com/AppImage/AppImages/blob/master/legacy/pythongtk 3hello/Recipe This sample contains the shell commands which need to be run in order to package your application as an AppImage Before following the instructions, you will need a thumbnail image for you application (tkedit.png in our case) and a desktop file to run it Here is an example desktop file for our editor (tkedit.desktop): [Desktop Entry] Name=tkedit Exec=tkedit Icon=tkedit.png Comment=A text editor with python syntax highlighting You will need to create the icon, tkedit.png, yourself With these two files ready, you can then begin the process of creating an AppImage for your editor Download and source the helper functions from the AppImages repository: $ wget -q https://github.com/AppImage/AppImages/raw/master/functions $ source /functions.sh Export variables which will be used throughout the script: $ export APP=TKEDIT $ export LOWERAPP=tkedit Create the directory at which we will place our AppImage: $ mkdir -p $APP/$APP.AppDir/ $ cd $APP/$APP.AppDir Create a virtual environment named usr inside this folder: $ python3 -m venv usr $ source usr/bin/activate sh -O /functions.sh Install our external dependency in this virtual environment: $ pip install PyYAML Copy your python modules into the bin directory of the virtual environment (ensure you have the tkedit.py file from the Windows section earlier): $ cp *.py usr/bin/ Remove the file extension from tkedit.py and mark it as executable: $ mv usr/bin/tkedit.py usr/bin/tkedit $ chmod +x usr/bin/tkedit Now, we can begin using the helper script functions to start doing the heavy lifting for us: $ get_apprun $ get_desktopintegration tkedit You will be asked if you want to add the desktop entry to your system This is up to you: $ copy_deps; copy_deps; copy_deps; $ delete_blacklisted $ move_lib 10 You application will now need a version number, set as an environment variable: $ export VERSION=1 11 We are now ready to package A file named AppRun will have been created in your current directory Run this file to test that the AppImage will work when executed: $ /AppRun 12 If all looks good, we are ready to package the AppImage: $ cd $ generate_appimage 13 After this command runs, you should have a new folder called out Inside here should be a binary file called something like TKEDIT-01.glibc2.3.4-x86_64.AppImage This is your binary file and can be run as follows: /TKEDIT-01.glibc2.3.4-x86_64.AppImage 14 If your AppImage was created successfully, you can now give this file to other people so that they can run your editor! macOS When packaging for macOS, cx_freeze may work for you However, there is another alternative named py2app, which we will take a look at now Ensure you have the tkedit.py file described in the Windows section earlier, then install py2app into our virtual environment using pip We will need version 0.13, since later versions not support Tkinter properly: $ source env/bin/activate $ pip install py2app==0.13 With py2app installed, you can go ahead and let it generate a setup.py file using its setup tools: $ py2applet make-setup tkedit.py This should overwrite your setup.py file with a new one We will need to add our PyYAML dependency to it, so it looks like so: """ This is a setup.py script generated by py2applet Usage: python setup.py py2app """ from setuptools import setup APP = ['tkedit.py'] DATA_FILES = [] OPTIONS = {'includes': ['PyYAML']} setup( app=APP, data_files=DATA_FILES, options={'py2app': OPTIONS}, setup_requires=['py2app'], ) With this taken care of, we can now install our dependencies and then execute the py2app command: $ pip install PyYAML $ python3 setup.py py2app This should create two new folders for you, named build and dist Your binary will be in the dist folder You can run it by referencing it from the terminal, a: $ /dist/tkedit.app/Contents/MacOS/tkedit If your editor pops up, congratulations! You have now created a macOS binary That covers everything for building packaged binaries You hopefully should now be ready to port over your Tkinter GUI applications to distribute to the rest of the world Of course, the more complicated the application, the more steps will be involved in getting it packaged; so, some in-depth reading of packaging Python applications is recommended The official guide can be found at https://d ocs.python.org/3/distutils/setupscript.html Summary In this chapter, we have looked at a few widgets which did not make their way into our example applications We saw that the LabelFrame widget allows us to surround a group of widgets with a heading, which can be either hardcoded or tied to a Label widget The Checkbutton and Radiobutton widgets were demonstrated, and we saw how to bind them to Tkinter's variables, such as IntVar objects, in order to return the user's choices We learned about the OptionMenu and Combobox widgets, which are used to make a choice from a list of pre-defined options The Combobox acts as a combination of an Entry widget and an OptionMenu widget, also allowing the user to enter their own value if necessary If we want to have a tabbed interface, we have now looked at how the Notebook widget allows us to display multiple frames in a window using tabs and we can assign each one a label to display in its tab After covering those widgets, we moved on to learning how to create binary packages for our text editor project After adjusting the application to store its configuration data in the user's home directory, we saw how to create a setup.py file, which allows the program to be installed with Python's package manager – pip The benefits and drawbacks of pip were mentioned and, then, we looked at packaging for each major desktop operating system independently We used cx_freeze to create a exe file for Windows, the AppImage suite to create a AppImage file for Linux, and py2app to create a app file for macOS That's it for Tkinter GUI Programming by Example We have now built three working desktop applications and are able to share them with the rest of the world via packaging I hope this book has shown you how easy it is to turn your simple Python scripts into full graphical applications or build a desktop application from the ground up Go forth and create! Feel free to share your work with me over on GitHub, where I can be found at https://github.com/Dvlv I look forward to hearing from you Other Books You May Enjoy If you enjoyed this book, you may be interested in these other books by Packt: Tkinter GUI Application Development Cookbook Alejandro Rodas de Paz ISBN: 978-1-78862-230-1 Add widgets and handle user events Lay out widgets within windows using frames and the different geometry managers Configure widgets so that they have a customized appearance and behavior Improve the navigation of your apps with menus and dialogs Apply object-oriented programming techniques in Tkinter applications Use threads to achieve responsiveness and update the GUI Explore the capabilities of the canvas widget and the types of items that can be added to it Extend Tkinter applications with the TTK (themed Tkinter) module Python GUI Programming Cookbook - Second Edition Burkhard Meier ISBN: 978-1-78712-945-0 Create the GUI Form and add widgets Arrange the widgets using layout managers Use object-oriented programming to create GUIs Create Matplotlib charts Use threads and talking to networks Talk to a MySQL database via the GUI Perform unit-testing and internationalizing the GUI Extend the GUI with third-party graphical libraries Get to know the best practices to create GUIs Leave a review - let other readers know what you think Please share your thoughts on this book with others by leaving a review on the site that you bought it from If you purchased the book from Amazon, please leave us an honest review on this book's Amazon page This is vital so that other potential readers can see and use your unbiased opinion to make purchasing decisions, we can understand what our customers think about our products, and our authors can see your feedback on the title that they have worked with Packt to create It will only take a few minutes of your time, but is valuable to other potential customers, our authors, and Packt Thank you! .. .Tkinter GUI Programming by Example Learn to create modern GUIs using Tkinter by building real- world projects in Python David Love BIRMINGHAM - MUMBAI Tkinter GUI Programming by Example. .. think Preface Welcome to Tkinter GUI Programming by Example We will be exploring how to use the Tkinter library, which is included alongside most Python installs This framework is very simple to. .. beginning and end Expanding our demo Using tags Searching text Adding syntax highlighting to our text editor The Highlighter class Using our Highlighter class The LineNumbers class Using our LineNumbers