Note: this is the second part of a series. For the first part, about the planning, click here.
As the first toolkit to experiment, I selected Tkinter, since I’m versed in Python and this already comes packaged with the Python standard distribution.
For a simple touch of history, Tkinter is a port to Python of TK, a library written in Tcl, being one of the oldest GUI frameworks, starting from 1992, starting to be used majorly in the Unix world, and from there to Windows, which was by that time in the version 3.0. Tk was ported to Python by Guido Van Rossum himself, the created of the Python language.
But, truthly speaking, I didn’t used the Tkinter API directly, but through a higher level interface provided by the PySimpleGUI library, a wrapper created with the idea of simplifying the development of Graphical User Interfaces (GUIs).
The ease of use provided by this library comes in handy about the way with deals with the organization of the components in the GUI. You won´t have to learn to choose the right layout manager when building a window, instead you use the components organized in something like a textual description, or a matriz of components, declared as an array.
layout=[[sg.Image(node.icon, size=(32, 32), k='icon')], [sg.Text('Title'), sg.Input( node.text, k='title_input')], [sg.Text('Path'), sg.InputText(node.values.exe_path if len(node.values) > 0 else '', k='path_input', enable_events=True), sg.FileBrowse(enable_events=True, target='path_input', k='path_browser', file_types=(("Executables", "*.exe"),) )], [sg.Text('Env ini'), sg.Input(node.values.env_ini if hasattr(node.values, 'env_ini') else '', k='env_ini_input', enable_events=True), sg.FileBrowse(enable_events=True, target='env_ini_input', k='env_ini_browser', file_types=(("Ini files", "*.ini"), ("Env files", "*.env")))], [sg.OK(), sg.Cancel()] ], resizable=False, modal=True, finalize=True )
produces the following window:
which is used to edit one app item in the list view.
One problem I came across is that Tkinter does not have natively the Drag and Drop feature, besides not having the possibility to have to have also a systray icon, which I had to implement separately using the pystray module, which I modified to add icons for each menu item.
Natively, Tkinter doesn’t support Windows icons not even JPEGs, in order to grab the icons embedded in the windows exe’s I had to use the low-level win32 api, which floods you in a wave of complexity just for a simple thing like getting the icon out of the executable. The MSDN library is prettly extensive in decribing all the functions like the ones of ExtractIconEx or GetBitMapBits. From there I had to convert internally the icon bitmap into a PNG with the help of the magnificent Python’s Pillow library that manipulates images.
PySimpleGUI also features the capacity to use if/then/else clauses to deal with each event. Instead of registering event handlers for each case, the method
window.read() returns the event name and the value of the component which triggered it. For simple use cases, and not complex ones, this eases much the hability to. Off course, as you are dealing with more complicated layouts, with you have deal with tenths of events, the matter is entirely different.
The app was coded under Windows, and tried it later to run under MacOS and Linux, using a default icon, and the application worked but had some nuances, and I had to install separately the Tk library.
Globally speaking, I would stand with this implementation if it was not the case that doesn’t support Drag and Drop and not working well under no-Windows environments. PySimpleGUI simplifies your life, but I think Tkinter is limited of what can do, taking as reference what you can do with GUIs nowadays.
The code is available at Github.