I would like to show the use of the Python Interpreter in applications. Though this is an MFC sample presented in the article, you are not limited to use it in MFC only. Any GUI toolkit can be used as the front end.
A Gtk implementation of the front end is also provided for which you will need the gtk 2.12 runtime installed, which is freely available.
Many of you might have seen the numeric input fields in most commercial CAD and scientific applications that facilitate the user to write mathematical expressions. This is to allow the user to use the edit box or the spinner box as a calculator on the fly. I was very much fascinated with this functionality and always wanted to easily have it in my applications. Writing a parser was a long job. When I just started learning Python, I came to know that it was a beautiful calculator by itself. You just need to type the expression on the command line and return -- you get the answer for any math function the C programmer is familiar with. After a long search on the net and the Python API doc, I finally came to know how to simply send a
string to the interpreter and retrieve the results. I leveraged this ability of the Python API to embed it into a dialog box.
Using the Code
For using the code, you need Python 2.5 installed. It is freely available. You must set the include and lib paths in your Visual Studio environment.
Generally if you install Python with the default installer settings, it gets installed in C:\Python25 folder.
You will find an 'include' folder, a 'Lib' folder and a 'libs' folder. Remember, the libraries are in the 'libs' folder and not in the 'Lib' folder.
The trick is that we will get the string the user enters in the edit control, pass it to the Python interpreter, get the result and write it back to the edit control. All this is done when the control loses focus.
Include the Python.h header.
Add the python25.lib to the additional libraries required.
double res = EvalExpression(m_Expr2);
double CPyEmbedMFCDlg::EvalExpression(CString iStr)
char* expr = iStr.GetBuffer(0);
PyObject * main_mod = NULL;
PyObject * main_dict = NULL;
PyObject * obj = NULL;
main_mod = PyImport_AddModule("__main__");
main_dict = PyModule_GetDict(main_mod);
PyRun_SimpleString("from math import *");
obj = PyRun_String(expr, Py_eval_input, main_dict, NULL);
if (obj != NULL)
lval = PyFloat_AsDouble(obj);
It is as simple as that. Every GUI toolkit gives you some or the other kind of text editing component. In MFC, I have used the
CEditCtrl in conjunction with the
CSpinButtonCtrl. In Gtk, you get the
GtkSpinButton withe the spinner integrated. The common thing is that you have to handle the focus losing event to call the evaluation code. In the Gtk sample, I have done it for both focus losing and keyboard's enter event.
In the sample provided, enter the mathematical expression in any edit control and press tab to change the focus and you will get the evaluated result in the control itself.
Note: To run the application, you need not have Python installed. The Python25.dll is shipped with the sample. Similarly you need to only ship the same when packaging your application.
Points of Interest
You can use all the C syntax of entering mathematical expressions including trigonometric functions and others. Constants pi and e are also supported. Refer to the Python manual for the supported mathematical calls.
See the function responsible to enable the math library functions:
PyRun_SimpleString("from math import *");
Building the example in debug mode
If you build the example in debug mode, you will get an error: "cannot open file "python25_d.lib". To resolve this issue, make a copy of the existing python25.lib in your python installation "libs" folder and rename it to python25_d.lib and it will compile. You need to do this to build the debug version only. The release version will build without issues. Inspite of adding python25.lib in Additional Dependencies in the Debug configuration linker input setting, this error appears, and so I have found this workaround. It would be helpful if someone can throw some light on this issue.
- 16th December, 2008: First release.. and probably final