Author Topic: Using IronPython to create Windows Applications  (Read 7938 times)

0 Members and 1 Guest are viewing this topic.

TR

  • Guest
Using IronPython to create Windows Applications
« on: September 26, 2006, 09:11:24 AM »
The following article is a brief tutorial on how to use IronPython to create a GUI program for testing regular expressions. The program itself doesn't have much real-world value but it should serve its purpose as an example of how to create a GUI program in IronPython.

Requirements:
*  Microsoft .NET 2.0 Runtime
IronPython 1.0
pyc.py (Part of the IronPython compile example from Microsoft)

Not required but recommended:
*  A good text editor that supports syntax highlighting for python files.

Lets Get Started

Before we get started with coding lets first set up our working environment for testing and compiling. In the folder that you're going to be hosting your code in create a new text document and rename it to something like "commandline.bat". Once created right click the document and select "Edit". In the document enter the following info; replacing "E:\IronPython-1.0" with location you unzipped IronPython to.

Code: [Select]
%ECHO OFF
path = %path%;E:\IronPython-1.0
cmd
%ECHO ON

This will allow us to launch this batch file and then issue simple commands such as "ipy code.py" for testing.

Code On

Now that we have our environment setup create a new text document and rename it to "validator.py". We now have our main program which you can open validator.py with your text editor of choice. We now need to define what assemblies or files we want to inherit functionality. To use .NET assemblies we will need to import the module "clr" which handles their loading. We know we want to use the "System.Drawing" and "System.Windows.Forms" .NET assemblies so we will import them as well. With that being said enter the following into your text document.

Code: [Select]
import sys
import clr
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")

This above code only links IronPython to those assemblies, it doesn't mean we can use their code yet. In order to use their code we then need to import them as we would any other python file. Knowing that we need "Point" and "Color" from System.Drawing and Application, Form, Label and TextBox  from System.Windows.Forms we can import them in a fashion that will allow us to use them in our code without calling their parent objects. A better description would be instead of typing "System.Windows.Forms.Label()" every time we want to reference a label we can simply call "Label()".

Code: [Select]
from System.Drawing import Point, Color
from System.Windows.Forms import Application, Form, Label, TextBox

We will also need to use functionality from IronPython's built in regular expression library so we will need to import that as well.
Code: [Select]
import re

Lets get to the Form

Now that we have everything set up to code using a mixture of Python and .NET we can get to the part of the program which we define our form. We will be using what is called "inheritance" in Python to define a class object in our code as a "System.Windows.Forms.Form".

Code: [Select]
class MainForm(Form):

We will then use the initialize method of our class ("__init__") to define our form and the controls on the forms. First lets define our forms layout. All properties being set here should need little explanation. Keep in mind that white spaces count in Python.

Code: [Select]
def __init__(self):
    #Define the layout of the form
    self.Text = "Regex Validator"
    self.Name = "Regex Validator"
    self.Height = 150
    self.Width = 300

Now that we have our form's properties defined we can start adding our controls to the form. We will be adding two labels and two textboxes. One textbox is for our regular expressions and the other is to type strings in to test them. I will not go into details on the creation of these controls as it is a fairly boring subject and what we are trying to accomplish should be fairly evident via our code. The one thing to note is that we have to define the location of our controls using Point from System.Drawing. For further reading on subjects regarding System.Windows.Forms and System.Drawing that aren't covered in the following code example it is advised to consult MSDN.

Code: [Select]
        #define the label for the regex 
        self.formulalabel = Label()
        self.formulalabel.Text = "Regex:"
        self.formulalabel.Location = Point(50, 25)
        self.formulalabel.Height = 20
        self.formulalabel.Width = 50
       
        #define the textbox for the regex
        self.formula = TextBox()
        self.formula.Location = Point(100, 25)
        self.formula.Height = 30
        self.formula.Width = 100
       
        #define the label for the test field
        self.testlabel = Label()
        self.testlabel.Text = "Test:"
        self.testlabel.Location = Point(50, 50)
        self.testlabel.Height = 20
        self.testlabel.Width = 50

        #define the textbox for the test field
        self.test = TextBox()
        self.test.Location = Point(100, 50)
        self.test.Height = 30
        self.test.Width = 100

        #add the controls to the form
        self.Controls.Add(self.formulalabel)
        self.Controls.Add(self.formula)
        self.Controls.Add(self.testlabel)
        self.Controls.Add(self.test)

 The above code defines all the items we need on our form and the locations at which we want them. Since we have everything defined and where we want them we can now add following lines of code that will allow us to launch our form from the command line. Basically we are defining "myform" as a new instance of "MainForm" which we will then launch using "Application" from System.Windows.Forms.

Code: [Select]
myform = MainForm()
Application.Run(myform)

We now have our form defined, it's controls and our method for launching it, and lets test it. Launch the commandline.bat from earlier on and issue the following command:
Code: [Select]
ipy validator.py

This should display our form. If your form isn't displayed please go back to your code and verify that your variables are named correctly and your white spaces are correct. You should see a traceback at the command line telling you where the error in your file is located. If your form did display correctly, congratulations you have just created your first form.


The Functionality

Great, we have a form that does nothing. The following little bit of code will check the regular expression we enter in the first textbox against the test string we enter in the second textbox. If the test string is a regular expression match the back color of the textbox of the test string will turn green, if not it will be red.

This should be defined outside of the __init__ function but still within the MainForm class.

Code: [Select]
    def checkfieldUpdate(self, sender, args):
        myregex = re.match(self.formula.Text, self.test.Text)
        if myregex:
            self.test.BackColor = Color.Green
        else:
            self.test.BackColor = Color.Red

We now have our event handler for when a user types in the test field but we have yet to attach it to an event. We will do this by running this function whenever the "KeyUp" event is fired on "self.test". Go back to the portion of code where we define the test textbox and add the following code below it. This will run "checkfieldUpdate" every time a user's key goes up.

Code: [Select]
        self.test.KeyUp += self.checkfieldUpdate

Final Test

Launch commandline.bat again and issue the command to launch the program again.
Code: [Select]
ipy validator.py

In the Regex field enter the following statement that will match any lower case alpha character:
Code: [Select]
[a-z]

Now in the Test field enter any lower case letter from a to z. This should turn the background of the textbox green. Erase that letter and enter any number. This should turn the background red. For better examples of regular expressions and how to test them run a Google search as it's out of the scope of this article.

Compiling the code

These scripts aren't very useful to distribute, as they require IronPython to run. Thankfully we can compile our Python code to native .NET executables that are much easier to distribute.

To accomplish this we first copy pyc.py to the same directory as validator.py. We then can launch commandline.bat and issue the following command, which will compile validator.py as a Windows executable named regex_validator.exe:

Code: [Select]
ipy pyc.py /main:validator.py /target:winexe /out:regex_validator.exe

Note: you can issue "ipy pyc.py" for a full list of pyc options.

After the program compiles we will need to copy "ironpython.dll" and "ironmath.dll" from your IronPython installation into the directory of our application. We can now distribute "validator.exe", "validator.pdb", "ironpython.dll" and "ironmath.dll" to any computer with the .NET 2.0 runtime installed and it will run as any other .NET executable would.

Conclusion

That concludes this example of creating a Windows Form Application using IronPython. I realize that this may not have been the best application for an example and my writing style probably leaves something to desire but hopefully you were able to see the power that IronPython brings to GUI development in Python as well as the ease of use it brings to .NET development. The method of constructing a GUI in IronPython might not be as easy as using an IDE in C# or VB.NET but it is rather straightforward and with a little practice it become quite easy.

Note: The code in the above example should run on Linux/Unix system if they have the latest version of Mono installed.

The Full Code

Below you will find the full code from our example:
Code: [Select]
#file: validator.py
#auth: Tim Riley

#import statements
import sys
import clr
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")
from System.Drawing import Point, Color
from System.Windows.Forms import Application, Form, Label, TextBox

import re

#the main form
class MainForm(Form):
    def __init__(self):
        #Define the layout of the form
        self.Text = "Regex Validator"
        self.Name = "Regex Validator"
        self.Height = 150
        self.Width = 300
       
        #define the label for the regex 
        self.formulalabel = Label()
        self.formulalabel.Text = "Regex:"
        self.formulalabel.Location = Point(50, 25)
        self.formulalabel.Height = 20
        self.formulalabel.Width = 50
       
        #define the textbox for the regex
        self.formula = TextBox()
        self.formula.Location = Point(100, 25)
        self.formula.Height = 30
        self.formula.Width = 100
       
        #define the label for the test field
        self.testlabel = Label()
        self.testlabel.Text = "Test:"
        self.testlabel.Location = Point(50, 50)
        self.testlabel.Height = 20
        self.testlabel.Width = 50

        #define the textbox for the test field
        self.test = TextBox()
        self.test.Location = Point(100, 50)
        self.test.Height = 30
        self.test.Width = 100
       
        #define the event handler. We are using KeyUp
        self.test.KeyUp += self.checkfieldUpdate
       
        #add the controls to the form
        self.Controls.Add(self.formulalabel)
        self.Controls.Add(self.formula)
        self.Controls.Add(self.testlabel)
        self.Controls.Add(self.test)
       
    def checkfieldUpdate(self, sender, args):
        myregex = re.match(self.formula.Text, self.test.Text)
        if myregex:
            self.test.BackColor = Color.Green
        else:
            self.test.BackColor = Color.Red
       
myform = MainForm()
Application.Run(myform)

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Re: Using IronPython to create Windows Applications
« Reply #1 on: September 26, 2006, 09:18:36 AM »
Can't wait to try this Tim, excellent article.  :kewl:
TheSwamp.org  (serving the CAD community since 2003)

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Using IronPython to create Windows Applications
« Reply #2 on: September 26, 2006, 09:49:11 AM »
That looks like an EXCELLENT tutorial Tim, good job!
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

TR

  • Guest
Re: Using IronPython to create Windows Applications
« Reply #3 on: September 26, 2006, 10:00:04 AM »
Thanks guys. As I read through it again I notice quite a few grammar mistakes and unquoted items that need to be quoted but that's the price you pay for writing a tutorial at 11pm I guess. Since they really shouldn't screw anyone up I will go back and fix them later.

I hope people at least give this a shot as it's a pretty neat way to create GUI applications using Python. If the manual method of creating a GUI is too much for people I believe it is possible to create a GUI template in C# using SharpDevelop or Visual Studio, compile it to a .dll and then import and use it in IronPython. I have yet to test this out but I will give it a shot tonight if I have time and post the results.

FengK

  • Guest
Re: Using IronPython to create Windows Applications
« Reply #4 on: September 28, 2006, 02:21:38 AM »
Thanks Tim.  There is an open source project named FarPy GUIE (http://farpy.holev.com/) which is a GUI builder and its lastest version allows user to export the form as python code or IronPython code.  The project is still in its early stage, but seems promissing.

TR

  • Guest
Re: Using IronPython to create Windows Applications
« Reply #5 on: September 28, 2006, 10:21:02 AM »
Dang...that is a truly awesome program, thanks for the heads up. I had heard mention of it before but wasn't aware it generated IronPython code. IMHO this makes IronPython GUI development as easy as C# or VB.NET.