Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / MFC

Embed Python in MFC Dialog

4.85/5 (18 votes)
13 Mar 2010CPOL3 min read 62.1K   3.9K  
Demo to show use of Python Interpreter to evaluate methematical expressions

MFC Version

Image 1

GTK+ Version

PyEmbedGtk.jpg

Introduction

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.

Background

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.

C++
BOOL CPyEmbedMFCDlg::OnInitDialog()
{
  ...
  ...
  Py_Initialize(); // Remember to Initialize the interpreter
  return TRUE;  // return TRUE unless you set the focus to a control
}
void CPyEmbedMFCDlg::OnEnKillfocusEdit2()
{
   // TODO: Add your control notification handler code here
   UpdateData();
   double res = EvalExpression(m_Expr2);
   m_Expr2.Format("%0.3f", res);
   UpdateData(FALSE);
}
double CPyEmbedMFCDlg::EvalExpression(CString iStr)
{
 double lval;
 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);
  return lval;
 }
 return 0.0;
}

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:

C++
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.

History

  • 16th December, 2008: First release.. and probably final

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)