EnglishSvenska

Rapidly building a python gui application

One of my favorite scripting languages is python, and for a couple of good reasons, and the most important reason rapid development from idea to a working application. I will show this with a example by building a simple python app with a gui and then make it ready for deployment by creating an executable file.

Prerequisites:

  • Python 2.7 (and not 3.* since wxpython support is still under development)
  • wxpython will handle the gui stuff.
  • wxformbuilder is a gui editor that can generate wxpython code for us. In most cases this is faster than writing this code by hand.
  • pyinstaller to freeze the application (create an .exe on Windows or a .app on osx)
  • A text editor (sublime, notepad++, pycharm or anything similar)
  • Good enough python skills to know how to install new modules. I will not explain how to install all the modules listed above.

1. Building the gui

Start wxformbuilder. By default a new project is already open. Set filename to gui and code generation to Python:

0 wxformbuilder 6 set project prop

Add a frame:

1 wxformbuilder form1.1 set form name

Add a wxBoxSizer. This will hold our gui components and stack them vertically:

2 wxboxsizer

Add a text and a button:

3 wxbitmapbutton

Name them m_text and m_button (or whatever):

5 set prop text4 set prop button

Bind an event for button clicks since we want to do something when the user clicks the button:

4.1 set prop button event

Save the wxformbulder project to a new folder. Then click Generate code from the menu.

7 generate code

The content of your project folder should contain the wxformbuilder project file and the generated file:

8 files

2. Integrate gui into Python code

The idea is to import the gui file, extend the functions and override the events. Lets use this code as a skeleton:

import wx
import gui

# Extend the gui with some new functionality
class MyFrame(gui.MainFrame):
    def __init__(self, parent, title):
        gui.MainFrame.__init__(self, parent)

    # this is the event we defined in wxformbuilder, and now override from gui.py
    def on_button_click_event(self, event):
        print('on_button_click_event')

# Create wxpython app
class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None, "Hello Wxpython")
        self.SetTopWindow(self.frame)
        self.frame.Show(True)
        print("wxApp created.")

        return True

if __name__ == "__main__":
    app = MyApp(redirect=False) # do not redirect stdout to the gui
    app.MainLoop() # render gui continuously

Try running the code and you should see something like this:
9 running the skeleton

Now lets modify it to do something when user clicks the button:

import wx
import gui

# Extend the gui with some new functionality
class MyFrame(gui.MainFrame):
    def __init__(self, parent, title):
        gui.MainFrame.__init__(self, parent)

    # this is the event we defined in wxformbuilder, and now override from gui.py
    def on_button_click_event(self, event):
        print('on_button_click_event')

# Create wxpython app
class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None, "Hello Wxpython")
        self.SetTopWindow(self.frame)
        self.frame.Show(True)
        print("wxApp created.")

        return True

if __name__ == "__main__":
    app = MyApp(redirect=False) # do not redirect stdout to the gui
    app.MainLoop() # render gui continuously

Now a button click should trigger the event and print something to the console:

10 running the finnished code

Building an executable (freezing) the application

Since Python is a script language we (usually) don't compile it into machine code. But if you want to deploy your application or send it user which do not have Python installed, you can freeze your application into an executable file (.exe in windows or .app in OS X). There are multiple tools to do this but I choose to use pyInstaller since it works on both windows and OS X, and can pack your application into a single executable instead of multiple files.

In principle, using pyInstaller is quite straight forward. From the terminal (OS X) or command prompt (windows), you can use this command to build your file:
# pyinstaller -y --windowed --onefile --icon=icon/banana.icns --name="' + filename + '" hello_wxpython.py

Build executable from a Python script

I usually use a custom script when I want to build an executable. You can download the pyinstaller_helper module from the github link at the end.

import pyinstaller_helper

pyinstaller_helper.build({
    'script': 'hello_wxpython_tutorial.py',
    'application_name': 'hello wxpython',
    'version': '1.0.0.1',
    'company_name': u'Example',
    'product_name': u'Hello wxPython',
    'internal_name': 'product_name',
    'original_filename': u'Hello wxPython',
    'file_description': 'Lorem ipsum.',
    'legal_copyright': 'your@email.com',
    'legal_trademark': ''
})

Running build_executable.py on OS X will generate an .app file, and on windows a .exe file. The script will create an executable that is specific for that platform, so for me it looks like this:

11 dist code

Download the code

This tutorial is on github.

Build a GUI in python using the Qt framework

If you would like to learn how to build a GUI using the Qt framework instead of Wxpython then try this sponsored link:

https://www.udemy.com/python-gui-programming/

Use the coupon code: sebastiannilsson.com and if you are one of the first 50 you get it for free.

Taggad med: ,
Kategori: Blog
7 Comments »Rapidly building a python gui application
  1. sebnil skriver:

    To add an icon:

    class MyFrame(gui.MainFrame):

    def __init__(self, parent, title):
    gui.MainFrame.__init__(self, parent)

    # set icon
    try:
    if hasattr(sys, 'frozen') and sys.platform == 'win32':
    # set icon on frozen win32 executable
    exeName = sys.executable
    icon = wx.Icon(exeName, wx.BITMAP_TYPE_ICO)
    self.SetIcon(icon)
    elif not hasattr(sys, 'frozen'):
    # set icon on pythpn script
    self.SetIcon(wx.Icon('icon/banana.ico', wx.BITMAP_TYPE_ICO))
    except:
    logger.error("Can't set icon\n")
    pass

  2. Assil skriver:

    Great tutorial. May I ask how large the packaged application was on OS X? It needs no other dependencies, correct?

    • Jeff Hoogland skriver:

      This is my question as well. Do the .exe and .app files created with this pyinstaller_helper have everything self contained to the user running them does not need python/pyqt installed manually?

      • Assil skriver:

        Yes, pyinstaller packages the required Python binaries and all the libraries used by your code. However I'm not sure if the user needs to install anything extra for wxwidgets.

    • sebnil skriver:

      Quite big; 24.6 Mb

      Sorry for late response. I have been abroad without internet for a while.

  3. UmarYusuf skriver:

    Thanks for this post. How soon will wxPython be ready for Python3.x?

  4. Carlos Monzón Reyes skriver:

    Do you have some example to use ribbon objects on wxFormBuider designer. I am beginner and appreciate to have some one like as guide.

Kommentera

E-postadressen publiceras inte. Obligatoriska fält är märkta *

*