/* jquery */ /* jquery accordion style*/ /* jquery init */
Showing posts with label Python GUIs. Show all posts
Showing posts with label Python GUIs. Show all posts

PyCon 2020 - Online Content

With the current global lockdown events like PyCon US 2020 have been cancelled.

However, you can still access plenty of Python technology news and information for free by subscribing to PyCon online./p>

Options include receiving email notifications and watching the PyCon 2020 YouTube Channel.

Content includes:
• Recorded talks and tutorials
• Online Summit and Hatchery programs
• Poster presenters sharing their creations
• Startup Row company presentations
• Sponsor workshop videos and job postings

Try My Free Python Coding Tutorials

Free Raspberry Pi GUI Coding Course

Do you want to learn how to build your own Graphical User Interface (GUI) with GuiZero?

Well, with this free Google supported GUI course learn how to incorporate interactivity into your apps by experimenting with different types of interface widgets - such as buttons and text boxes.

Topics covered include:
• Design with boxes and auto or grid layouts
• Responding to user inputs using events
• Reading and modifying the widget properties
• Handling time-based events
• User optimisation techniques
• Splitting projects into manageable chunks

Try My Free Python Coding Tutorials

Raspberry Pi in Easy Steps - Book Review

The ‘Easy Steps’ books are well known for their excellent layout, clear and concise text and easy-to-follow instructions. It’s a format that ensures this Raspberry Pi in Easy Steps book is a great choice for anyone beginning their Raspberry Pi journey.

Inside author Mike McGrath kicks off with a basic introduction to the Pi. You’ll become familiar with the board’s components, the startup and login process, the graphical desktop and the underlying file system. An overview of the Linux command line completes this section.

The rest of the book is devoted to writing code. As a gentle start it begins with the Scratch language, where you’ll snap-together various blocks to build event-based animations using its stage, sprites, costumes and sounds.

All the remaining sections focus on the far more flexible Python language. Topics include the Python command-line interpreter, data structures (lists, tuples, sets and dictionaries), loops, functions, modules and file I/O. Then it moves on to building simple games with the pygame module and creating tkinter GUI apps. Lastly, there’s a short introduction to interfacing with the Pi board's GPIO pins.

In summary this book is an excellent introduction to Raspberry Pi coding. Follow the steps all the way through and you’ll be in a position to tackle a wide range of Python coding projects. And remember, the Python language is also available for Windows, macOS and most other Linux platforms.

My Free Raspberry Pi Python Coding Tutorials

From tkinter to AppJar (part 3)

In the previous tutorial, From tkinter to AppJar (part 2), we converted the file search tkinter app from an earlier tutorial to a shorter 30 line AppJar app.

This time we'll take the same file search app and add new code lines to enhance the user interface's look and feel via a series of configuration options.

With your favourite Python 3 editor open the previous file search code listing, then change the init() function to look like the listing below:

Let's take a closer look at the behaviour introduced by these new code lines.

On line 6 we create a splash screen with an appropriate text label.

On line 7 we set the background colour of the app window, in this case to orange.

On lines 8 and 9 we set the font size of the text labels and the buttons. Notice here the button font size is a little larger than the label font size.

Finally, on line 17 we ensure the "Start Path" text entry field is associated with the initial cursor focus.

You can find more information on AppJar's extensive widget collection and configuration capabilities at the official AppJar website.

Try My Free Raspberry Pi Python Coding Tutorials

From tkinter to AppJar (part 2)

In the previous tutorial, From tkinter to AppJar (part 1), we converted a simple tkinter app to a short 8 line AppJar app.

This time we'll try out some of the other App Jar widgets by converting a tinter-based file search app from a previous tutorial.

With your favourite Python 3 editor, open a new code file and enter this code:

As you can see, we've replicated the functionality of the 53 line tkinter file search example with just 30 lines of AppJar code.

In part 3 we'll add new code lines to enhance the user interface's look and feel via a series of configuration options.

Try My Free Raspberry Pi Python Coding Tutorials

From tkinter to AppJar (part 1)

As part of my free Raspberry Pi Python Coding tutorial series I showed how to create Graphical User Interfaces with the tkinter module.

However, while it's a very flexible piece of software, writing tkinter apps tends to involve quite a bit of code. In this post I'll look at a lightweight GUI alternative called AppJar.

Although App Jar is based on tkinter, it removes the need for much of the so-called 'boilerplate' code. And this means we can focus our attention on widget-based UI design.

Install AppJar

First, you'll need to install AppJar.

The easiest way is to use the following pip command:
sudo pip3 install appjar

Alternatively, download Appjar, unzip it and move the appjar folder to your source code folder.

Simple AppJar Example

Let's start with an AppJar version of my single button callback tkinter tutorial (which included a detailed walk-through of the code).

With your favourite Python 3 editor, open a new code file and enter this code:

Notice the size of this program. We've replicated the functionality of the 25 line tkinter example with just 8 lines of AppJar code.

In part 2 we'll converting a tinter-based file search app to App Jar.

Try My Free Raspberry Pi Python Coding Tutorials

Tkinter Coding with AppJar and GuiZero

Previously we had a look at creating Graphical User Interfaces with Tkinter as part of my free Raspberry Pi Python Coding tutorial series.

Tkinter is certainly a very flexible piece of software, capable of implementing all kinds of user interface (UX) designs. However, the lines of code needed to create usable solutions tends to rise quite quickly. This can make things a little difficult for those with relatively limited Python coding experience.

Recently a couple of Tkinter-based Python modules have started to address this issue. One is GuiZero and the other is AppJar.

The idea behind these modules is to simplify the creation of grid-styled form-based apps, while still supporting a wide variety of widgets. Both are easy to install and use. Although be aware that as they are still in development sfeatures are subject to change and you may encounter the occasional bug.

AppJar documentation is based around a 'code sandwich' metaphor with a menu of widget-based fillings. Code examples include Minecraft interaction and there's also a series of hands-on AppJar coding tutorials.

The GuiZero documentation is also straightforward to follow with plenty of code examples, such as how to use the multi-cell Waffle grid layout.

Try My Free Raspberry Pi Python Coding Tutorials

Learn Python - GUI File Search App

Now we've seen how a typical GUI program is structured, let's try a more advanced example.

It will be based on the File Walk App we created earlier, which searched the file system, using the os.walk function to obtain a list of files and sub-directories.

Open another new file in Geany, save it as 'tk-search.py' and type in the code below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# A GUI search program using tkinter
# Created by David Briddock

from tkinter import *
import os

# initialise main window
def init(win):
  win.title("File Search")

  labelPath.grid(row=0, column=0, sticky="W")
  entryPath.grid(row=1, column=0)
  labelEnding.grid(row=2, column=0, sticky="W")
  entryEnding.grid(row=3, column=0)
  btnSearch.grid(row=4, column=0)
  fileList.grid(row=0, column=1, rowspan=5)
  yscroll.grid(row=0, column=2, rowspan=5, sticky="NS")

  fileList.configure(yscrollcommand = yscroll.set)
  yscroll.configure(command = fileList.yview)
  entryPath.insert(INSERT, "/home")
  entryEnding.insert(INSERT, ".py")

# find button callback
def search():
  # get start directory and file ending
  startDir = entryPath.get()
  fileEnding = entryEnding.get()

  # clear the listbox
  fileList.delete(0, END)

  # find matching file and fill listbox
  for path, dirs, files in os.walk(startDir):
    for fileName in files:
      if (fileName.endswith(fileEnding)):
        fileList.insert(END, path+"/"+fileName)

# create top-level window object
win = Tk()

# create widgets
labelPath = Label(win, text="Starting Path")
entryPath = Entry(win, width=12)
labelEnding = Label(win, text="File Ending")
entryEnding = Entry(win, width=12)
fileList = Listbox(win, width=80)
yscroll = Scrollbar(win, orient=VERTICAL)
btnSearch = Button(win, text="Search", width=8, command=search)

# initialise and run main loop
init(win)
mainloop()

While there are quite a few lines of code here, I hope you can pick out the function definitions and typical GUI app structure.

We've still have our tkinter module import on line 4, while line 5 imports the os module. You'll also notice the init function and another event callback function, this time called search. More on these later.

More Widgets

On line 40 we create the top-level window object. This time we need quite a few widgets. These are created on lines 42 to 49.

The labels and entry boxes will provide our user input interface. The label text is set using the text configuration parameter. The two entry fields will hold the starting directory and file ending strings, and have a display width assignment of twelve characters.

On line 47 a listbox widget is created. This will hold a list of matched files. Specifying a width of 80 characters will cater for any long path names. A search might find many files. So, we need a vertically oriented scrollbar. We'll 'attach' this scrollbar to the listbox later.

And finally, on line 49, we create a button widget to kick off the search operation. The three parameters specify the button label text, the callback function name, and a width of eight characters.

Lines 52 and 53 call the init function and start the main window loop, just like we saw in the Basic GUI App post.

Using Grid Layout

Now back to the init function. With more widgets it's quite a bit longer than before, and there's also something new to learn. Our widgets need to be positioned in particular locations. Luckily, the Tkinter module has a built-in grid layout feature.

You can think of a grid layout as a collection of empty boxes or cells, organised into rows and columns - very like the cells in a spreadsheet. The cells are numbered from the top left corner starting from zero. A widget is placed in a particular grid cell with the widget's grid function.

We start on line 11 with the cell at column zero row zero, which will contain the starting directory label widget. On line 12 we populate the cell in column zero row one with the starting directory entry widget. Lines 13 and 14 repeat this process for the file ending's label and entry widgets for rows three and four. On line 15 we add the search button to row five in column zero.

By now I'm sure you noticed the sticky configuration parameter on the labels. The 'W' setting means 'West' and ensures the label text will line up on the left hand side of the column.

The second column, column one, only contains the listbox widget. However, the rowspan configuration parameter will stretch it to fill five rows - matching the number or rows we assigned in column zero.

The final column has the scrollbar. This is also stretched over five rows and has a 'NorthSouth' stickiness to ensure it fills the full column space. We 'attach' the scrollbar to the listbox using the statements on lines 19 and 20. This will ensure the listbox contents scroll when the scrollbar is moved.

The last two lines of the function, 21 and 22, set default text string values for the entry widgets.

The Search Callback

Now for the search function. Remember this is called when the search button is clicked, as per the callback setting on line 49. The first two lines, 27 and 28, extract the contents of the entry widgets and store them in two string variables, startDir and fileEnding.

Line 31 deletes all the items in the listbox, to remove any files from a previous search.

Our search is done in lines 34 to 37. Line 34 starts a loop and calls the os.walk function with our startDir string. This function returns a list of paths, files and sub-directories. Line 35 is another loop which extracts each file in the file list, and stores it in the fileName variable.

The conditional if statement on line 36 compares the end of the fileName string with our entered fileEnding. If the test is True then it adds a new string to the listbox, using the path and file name.

And that's it. Run the program using Geany's Build->Execute menu option, or F5 key.

Experiment by trying different file endings and starting directories.

Make It Your Own

As we've seen a GUI program requires quite a bit more code than a simple terminal-based one. However, the flexibility offered by a widget-based user interface is certainly worth the effort.

GUI programming is a big subject. In this short article we've barely scratched the surface. The possibilities for refinement are almost endless. For example, you could change a widget's size or colour, add new widgets, or create a completely different layout.

Python 2.7

Remember, for Python 2.7 you'll need to install Tkinter. If you see a message that says 'No module named Tkinter' then take a look at my previous Installing Tkinter post.

A post from my Learn Python on the Raspberry Pi tutorial.

Learn Python - Basic GUI App

Now it's time to write a GUI app.

Boot up your Raspberry Pi and open your Python editor. Next open a new file and save it as tk-basic.py in the Desktop's Python folder.

Now type in the code below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# A basic GUI program using tkinter
# Created by David Briddock

from tkinter import *
from tkinter import messagebox

# initialise main window
def init(win):
  win.title("My GUI")
  win.minsize(200, 50)
  btn.pack()

# find button callback
def hello():
  messagebox.showinfo("Hello", "Callback worked!")

# create top-level window object
win = Tk()

# create a widget
btn = Button(win, text="Hello", command=hello)

# initialise and start main loop
init(win)
mainloop()

Before we run this app let's examine the code in detail.

Basic Flow

After the program-level comments there's a tkinter module import statement on line 4. However, you'll notice it's a little different to the ones we've used before.

What this style of import does is alleviate the need to prefix all the tkinter modules constants and functions. We'll need quite a few tkinter constants and functions for any reasonably sized GUI program, so this import option will help de-clutter the code - and save quite a bit of repetitive typing.

On line 5 there's a more specific import statement for the tkMessageBox module.

In order follow the program execution flow we need to skip past the function definitions and look further down the listing.

Window And Widget Creation

At line 18 we create a top-level window object and assign it to the variable win.

On line 21 we have the one and only widget, a button. When we create a widget we need to say where it fits in the window hierarchy. This is done by specifying the parent window as the first parameter. Widget characteristics are set by defining one or more optional parameters. Here we have specified two.

The text parameter will set the button's text label. The command parameter defines the callback function name. When a mouse click event occurs for this button, the named function is called, in this case hello.

Initialise And Loop

It's lines 24 and 25 that hold the key to the program's operation. On line 24 we call the init function to perform any initialisation operations. We'll look at this in detail shortly.

On line 25 there's the main GUI loop. It's an endless loop which only terminates when the window is closed. Entering this loop will cause the main window to be displayed, along with any widgets we've defined. Once running it will capture and process all keyboard and mouse events. If these events are associated with any widgets, such as our button, the appropriate callback function will be called.

Initialisation Function

As we saw earlier, line 24 calls the init function. In this basic program init contains just three lines.

On line 9 we set the top-level window title, which will appear in the titlebar. On the next line we specify the minimum size for our window in pixels. In this case it's 200 pixels wide and 100 pixels high.

The final function statement, on line 11, calls the Tkinter pack function on behalf of our button. This adds the button to its parent window, namely the top-level window win.

The Callback Function

The callback function, hello, is defined on line 14. Remember, callback functions never have any parameters.

Once again this is a small function with just a single line of code, which calls the tkMessageBox module function showinfo. This function creates a new popup-style window, and you'll notice it has two parameters. The first parameter will define the string in the window's titlebar. While the second parameter is the message that will appear inside the popup window.

Run The App

Now we can execute the app, using the Geany Build->Execute menu option or the F5 key. After the window appears click on the button to see the message window popup.

Because the callback is only associated with the button, if you click somewhere else inside the top-level window nothing happens.

Python 2.7 code

Here's the Python 2.7 version of the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# A basic GUI program using Tkinter
# Created by David Briddock

from Tkinter import *
import tkMessageBox

# initialise main window
def init(win):
  win.title("My GUI")
  win.minsize(200, 50)
  btn.pack()

# find button callback
def hello():
  tkMessageBox.showinfo("Hello", "Callback worked!")

# create top-level window object
win = Tk()

# create a widget
btn = Button(win, text="Hello", command=hello)

# initialise and start main loop
init(win)
mainloop()

A post from my Learn Python on the Raspberry Pi tutorial.

Learn Python - Installing Tkinter

Python 3.x

If you're using a recent version of Python 3, say version 3.6 or 3.7, then the tkinter module is preloaded. So you can move on to the next tutorial.

Python 2.7

However, if you're using Python 2.7 then you might need to install the Tkinter module.

To check if it's already installed open a new Python interactive session, then enter this statement (making sure there's an uppercase T in Tkinter):

>>> import Tkinter

Did you see an    ImportError: No module named Tkinter    error message?

If the answer is yes then follow the installation steps below (which are applicable to the Raspbian Jessie distro or the older Raspbian Wheezy image).

Ensure your Raspberry Pi is connected to the Internet, open an LXTerminal window and enter this command:

sudo apt-get install python-tk

If prompted enter the your login password, and reply y to any prompts.

Now we're ready to create GUI apps.

A post from my Learn Python on the Raspberry Pi tutorial.

Learn Python - GUI Event Handling

Event handling is a critical aspect of GUI app development. Events can be generated in various ways, keyboard and mouse interaction being two obvious examples.

A GUI program must be able to determine which key was pressed. Not just the alphanumeric keys, but also shift keys, control keys, alt keys, function keys, cursor keys, the escape key and special keys like the Windows key.

As for the mouse, a program needs to determine the current coordinates of the mouse pointer, whether a mouse button has been clicked and if the scroll wheel has moved.

How do we do this? In a GUI program it's done with something called 'callbacks'. A callback is registered against a particular widget, and associated with a specific function. When an event occurs in the widget's window area, the function is called. This function can then analyse the event type and respond appropriately.

Once again all this functionality is contained within the tkinter module, so creating a GUI callback is a straightforward operation.

A post from my Learn Python on the Raspberry Pi tutorial.

Learn Python - GUI Code Structure

GUI programs tend to have more code than simple terminal-based ones. This extra code might look a little daunting to the novice programmer. However, it's not as confusing as it might at first seem.

Every GUI application has a similar structure. Understand this structure and you'll be able to create any number of GUI apps, from the simple to the highly complex.

A typical GUI program has four main parts:

window and widget definition
 top-level window initialisation
 the main window loop
 event handlers

The first two parts define the look and feel of the GUI app. As the number of widgets grows and the design becomes more complex we'll have to increase the quantity of code in these parts.

The next two parts control the runtime operation of the app. After the loop renders the various windows and widgets onto the display it continually checks for new mouse and keyboard events. These events are subsequently processed by the previously defined event handlers.

To demonstrate each of these sections we'll create a simple tkinter app. But first, let's talk a little more about GUI events.

A post from my Learn Python on the Raspberry Pi tutorial.

Learn Python - GUI Windows

From a user's perspective GUI applications tend to look very different from one another. For example, on the Raspberry Pi's desktop the Geany application doesn't seem to have much in common with the File Manager utility. However, this isn't the case.

GUI apps are assembled from a collection of windows. All these windows are arranged in a hierarchy. Most of us recognise the typical application window frame, with its bar containing the app name and an array of window management buttons to iconise, maximise and close the window.

Inside this main frame there's a top-level window containing an assortment of GUI elements, generally referred to as widgets. Buttons, labels, text boxes, images, scrollbars, selection boxes and sliders are all types of widget. However, did you realise that all these widgets are themselves little windows. In fact, each widget may itself contain other widgets.

Every widget has its own specific list of properties, such as location, size and colour. Very importantly, a widget is aware of certain kinds of events within its window area, such as a key press or a mouse click. I'll talk more about GUI events in a future post.

If all this sounds a little complex, don't worry, there's good news in the form of a Python 3 module called tkinter, (or Tkinter for Python 2.7). This module has a collection of GUI-specific functions to simplify GUI coding. So let's get started.

A post from my Learn Python on the Raspberry Pi tutorial.