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 StartedBefore 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.
%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 OnNow 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.
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()".
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.
import re
Lets get to the FormNow 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".
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.
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.
#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.
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:
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 FunctionalityGreat, 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.
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.
self.test.KeyUp += self.checkfieldUpdate
Final TestLaunch commandline.bat again and issue the command to launch the program again.
ipy validator.py
In the Regex field enter the following statement that will match any lower case alpha character:
[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 codeThese 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:
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.
ConclusionThat 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 CodeBelow you will find the full code from our example:
#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)