Ultra Quick GUIs with wxFormBuilder/Python

I’ve been a fan of wxFormBuilder for a a long time. It allows programmers like me to develop highly polished GUIs for Real World Applications or quick, temporary GUIs just to get the job done. To follow the below steps won’t take more than 15 minutes. The Goal is to build a usable calculator using wxPython and wxFoemBuilder

Things you’ll need

Python
wxPython
wxFormBuilder

Any versions will do as long as they are inter compatible. I used Python 2.7.3 (32-bit), wxPython 2.8.12.1 (msw-unicode) and wxFormBuilder 3.2.3-beta (unicode)

Install all the above in thee order mentioned and we should be good to go.

Enter wxFormBuilder

Start wxFormBuilder and you’ll be greeted with New Project with a blank grey area in the center. Go to the Object Properties Window on the right and change name,file and set code generation to Python

1

From the Forms tab Choose Frame
3

Choose The Recently Added Frame from the object Tree and change name to MainFrame
4

Add a wxBoxSizer from Layout tab , make sure that orient is wxVERTICAL from the Object Properties

5

From the Common tab add TexCtrl and 2 Buttons.

6

Select each of these 3 elements and enable Expand and Stretch

7

Select the TextCtrl and change the name to text

8

Choose any button and rename it to solveButton and change the label to Solve

9

In the Events Tab change the OnButtonClick value to solveFunc. This will be the function called when the button is clicked.
10

Similarly rename the other Button to clearButton and change OnButtonCick to clearFunc

Your window should be looking similar to this by now.

11

Save The Project and hit F8 to generate code. You should end up with a file called gui.py in the directory you saved in. This file holds the code for generating the graphics.

Almost There

The final bit is writing the python code. Create a new python file in the same directory, and copy this code into it

Read the comments for explanation.

#importing wx files
import wx

#import the newly created GUI file
import gui

#importing * : to enable writing sin(13) instead of math.sin(13)
from math import *

#inherit from the MainFrame created in wxFowmBuilder and create CalcFrame
class CalcFrame(gui.MainFrame):
    #constructor
    def __init__(self,parent):
        #initialize parent class
        gui.MainFrame.__init__(self,parent)

    #what to when 'Solve' is clicked
    #wx calls this function with and 'event' object
    def solveFunc(self,event):
        try:
            #evaluate the string in 'text' and put the answer back
            ans = eval(self.text.GetValue())
            self.text.SetValue (str(ans))
        except Exception:
            print 'error'
    #put a blank string in text when 'Clear' is clicked
    def clearFunc(self,event):
        self.text.SetValue(str(''))

#mandatory in wx, create an app, False stands for not deteriction stdin/stdout
#refer manual for details
app = wx.App(False)

#create an object of CalcFrame
frame = CalcFrame(None)
#show the frame
frame.Show(True)
#start the applications
app.MainLoop()


The File contains less than 20 Lines of functional code.
All hail Python !!

If you are using IDLE on windows you can run this by clicking on Run Module and on Linux you can use python file.py where file.py is the file with the above contents. ( Thanks No more commandline )

Usage

Insert any valid mathematical expression in the Text Box and get the result
12

13

Advertisements

41 thoughts on “Ultra Quick GUIs with wxFormBuilder/Python

  1. Thanks. Had to debug, though (Value instead of Label):

    def solveFunc(self,event):
    try:
    #evaluate the string in ‘text’ and put the answer back
    ans = eval(self.text.GetValue())
    self.text.SetValue (str(ans))

    • Hi Vighnesh,thank you for share your Tut.Could you please explain, how I get acces to a Listbox outside
      the gui.file
      Thanks in advance

      • Any element from the gui module created by the form builder should be accessible with as an attribute of the CalcFrame class. Inside the class you would do self.listbox

  2. XP Professional Version 2002 SP3
    wx.version() = 2.9.4.0 msw (classic)

    Oops. I thought I had the “stable” version. Tried this code on Win7 32bit machine with wx.version() = 2.8.12.1 and it worked just fine.

    Thank you very much for writing this demo. It did indeed “simplify” basic forms for me!

  3. sorry did not tell you what i was texting about “Ultra Quick GUIs with wxFormBuilder/Python”
    p.s. have you done any more wxFormBuilder/Python tutorials

  4. Thanks. Most helpful tutorial on wxformbuilder and python I have found. Been trying to figure out value of text box for 3 hours, keep it up, noobs like me can use all the help they can get

    • I didn’f follow one specific source I can remember about for wx. And after this post I havn’t done much of wx. Although I found the solutions to most of my problems in the wxPython manual.

  5. hello,
    Thanks for this tuotorial, i have no python on code generation, I am using ubuntu 14.04, and I have installed all related
    An idea?

    Thanks

  6. After solving version issues with wxformbuilder, I have finished the tuto, but the program does not work, if I click on clear, nothing happens, and if click on solve button, a error appera on terminal.

    This is the code generated by the builder:
    import wx
    import wx.xrc

    ###########################################################################
    ## Class MainFrame
    ###########################################################################

    class MainFrame ( wx.Frame ):

    def __init__( self, parent ):
    wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 285,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )

    self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )

    bSizer2 = wx.BoxSizer( wx.VERTICAL )

    self.text = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
    bSizer2.Add( self.text, 0, wx.ALL, 5 )

    self.clear = wx.Button( self, wx.ID_ANY, u”Clear”, wx.DefaultPosition, wx.DefaultSize, 0 )
    bSizer2.Add( self.clear, 0, wx.ALL, 5 )

    self.solveButton = wx.Button( self, wx.ID_ANY, u”Solve”, wx.DefaultPosition, wx.DefaultSize, 0 )
    bSizer2.Add( self.solveButton, 0, wx.ALL, 5 )

    self.SetSizer( bSizer2 )
    self.Layout()

    self.Centre( wx.BOTH )

    # Connect Events
    self.clear.Bind( wx.EVT_BUTTON, self.clearFunc )
    self.solveButton.Bind( wx.EVT_BUTTON, self.solveFunc )

    def __del__( self ):
    pass

    # Virtual event handlers, overide them in your derived class
    def clearFunc( self, event ):
    event.Skip()

    def solveFunc( self, event ):
    event.Skip()

    The code for actions is which you show above.

    Am I missing something?

    Best Regards

      • Hello,
        I hope be doing the right way…
        # -*- coding: utf-8 -*-

        ###########################################################################
        ## Python code generated with wxFormBuilder (version Sep 17 2014)
        ## http://www.wxformbuilder.org/
        ##
        ## PLEASE DO “NOT” EDIT THIS FILE!
        ###########################################################################

        import wx
        import wx.xrc

        ###########################################################################
        ## Class MainFrame
        ###########################################################################

        class MainFrame ( wx.Frame ):

        def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 285,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )

        self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )

        bSizer2 = wx.BoxSizer( wx.VERTICAL )

        self.text = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer2.Add( self.text, 0, wx.ALL, 5 )

        self.clear = wx.Button( self, wx.ID_ANY, u”Clear”, wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer2.Add( self.clear, 0, wx.ALL, 5 )

        self.solveButton = wx.Button( self, wx.ID_ANY, u”Solve”, wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer2.Add( self.solveButton, 0, wx.ALL, 5 )

        self.SetSizer( bSizer2 )
        self.Layout()

        self.Centre( wx.BOTH )

        # Connect Events
        self.clear.Bind( wx.EVT_BUTTON, self.clearFunc )
        self.solveButton.Bind( wx.EVT_BUTTON, self.solveFunc )

        def __del__( self ):
        pass

        # Virtual event handlers, overide them in your derived class
        def clearFunc( self, event ):
        event.Skip()

        def solveFunc( self, event ):
        event.Skip()

        I am not understanding the comment “Virtual event handlers, overide them in your derived class”, in facy there are two function on the another one py file and it is there where the error appear.

    • Hello Orlando

      Virtual functions simply mean they do nothing, and you override them in your code to implement your own logic. Please paste your code on http://pastebin.com/ and share the link. It would be really helpful if I could see both your code and the generated code. Also mention the error you are getting.

      Again, please share the code through pastebin or some other code sharing facility. I cannot debug without indentation. And comments is not the right place to share code.

      Thanks
      Vighnesh

      • Thanks my friend
        Finnally (I believe), have a pastebin link to share with you

        http://pastebin.com/embed_iframe.php?i=f2MBpAxh

        The error what appear is in console, when I click on solve button the word “error” appear on console, it seems the flow goes by exception, I did a test in console with eval and works, so I do not understand why on runtime it does not
        Thanks in advance

    • Hi Vighnesh,
      I have tested the code recommended but still the clear button do nothing and solve button when is clicked does not give the expected result and an error is showed in console:
      Traceback (most recent call last):
      File “/home/orlando/PythonGui/calc.py”, line 23, in solveFunc
      ans = eval(self.text.GetLabel())
      File “”, line 0

      ^
      SyntaxError: unexpected EOF while parsing
      Thanks for your help.

      • Hello Orlando

        I am sorry for not testing the code on Linux. Use GetValue and SetValue instead of GetLabel and SetLabel and it should work. Thanks for pointing this out.

        Thanks
        Vighnesh

      • change line 23 to: self.text.SetValue(str(ans))
        and change line 28 to: self.text.SetValue(str())
        That should fix things πŸ™‚

  7. Hay hay!
    There is some errors in the code you have told us to copy 😦
    Maybe you could edit it with these changes πŸ™‚

    I changed this:
    def solveFunc(self,event):
    try:
    #evaluate the string in ‘text’ and put the answer back
    ans = eval(self.text.GetValue())
    self.text.GetValue (str(ans)) ####### Should be “SetValue”
    except Exception:
    print ‘error’
    #put a blank string in text when ‘Clear’ is clicked
    def clearFunc(self,event):
    self.text.SetValue() ####### SetValue(str()) fixes the SyntaxError: unexpected EOF while parsing

    To this:
    def solveFunc(self,event):
    try:
    #evaluate the string in ‘text’ and put the answer back
    ans = eval(self.text.GetValue())
    self.text.SetValue(str(ans))
    except Exception:
    self.text.SetValue(str(“I need math”))
    #put a blank string in text when ‘Clear’ is clicked
    def clearFunc(self,event):
    self.text.SetValue(str())

    That fixes all the reported errors
    Thanks for the great info you def helped me get started with wxformbuilder.
    http://pastebin.com/6FFyFsqz

  8. Thanks for this post!
    It was very useful to understand WxPython+WxFormBuilder.

    Here’s the Tkinter version (I think it’s easier than WxPython):
    # Import Tkinter (Tcl/Tk GUI library binding)
    from Tkinter import *
    # Import ttk for themed widgets (native look ‘n feel on Windows)
    import ttk

    # Function to solve the expression
    def solveFunc():
    try:
    res = eval(text.get())
    text.delete(0, ‘end’)
    text.insert(‘end’, str(res))
    except Exception:
    print ‘error’

    # Function to clear the text box
    def clearFunc():
    text.delete(0, ‘end’)

    # Create the Window
    root = Tk()
    # Create a Frame the window looks native under ttk
    panel = ttk.Frame(root)
    # Create a text box
    text = ttk.Entry(panel)
    # Create the buttons, with their parent widget, text and function associate to click event
    solveButton = ttk.Button(panel, text=’Solve’, command=solveFunc)
    clearButton = ttk.Button(panel, text=’Clear’, command=clearFunc)
    # Display the widgets filling the spaces
    panel.pack(fill=BOTH, expand=1)
    text.pack(fill=BOTH, expand=1)
    solveButton.pack(fill=BOTH, expand=1)
    clearButton.pack(fill=BOTH, expand=1)
    # Main Loop
    root.mainloop()

  9. The gui file gives an error. It says expected an indented block.
    self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )

  10. Thanks, that’s a really simple post and to the point.

    have you tried the same combination (wxPython, wxFormBuilder) on larger scales. How do you compare it with PyQt and Qt Designer ?

    Thanks.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s