How to refresh a wxPython GUI rom C++ ?

Dear All,

I would like to refresh a list of log entry messages (= a list of string)
that is displayed in a wxPython GUI from a C++ application.

1. I first tryed to import a C++ method in wxPython to set a pointer on a
refreshGUI method defined in the Python script
Problem: the pointer on the wxPython method is not callable
2. I then tryed to import a C++ method in wxPython that processes the
refresh
Problem: I cannot pass a list of string to wxPython. I do not know how to
use Py_BuildValue to pass a list of string.

Details of the tries:

1. Trying to call a wxPython method from C++
1.1. I first defined the following method in the wxPython script:

   def refreshLogList(self,items):
  self.LogList.Clear()
  self.LogList.InsertItems(items,0)

The following syntax works fine from within the wxPython script:

  items = ("1 First Log Message",
           "2 Second Log Message")
  self.refreshLogList(items)

1.2. I then tryed to call the method refreshLogList from C++
I defined a method in C++ to get a pointer on the refreshLogList method:
static PyObject* setGUI_RefreshPointer(PyObject *self, PyObject *args)
{
  //Here I try to extract the pointer from args using PyArg_ParseTuple and
store it in a local C++ variable declared like this: "static PyObject*
myGUI_RefreshPointer"
}

In the wxPython script I call setGUI_RefreshPointer(refreshLogList)

=> this all seems to work correctly and running my C++ application step by
step, I get a pointer address in myGUIPointer.

The problem is that that pointer is not callable. As checked by the
following instructions:

    int result;
    result = PyCallable_Check(myGUI_RefreshPointer);
    if (result == 1)
    {
      PyObject_CallFunction(object,NULL);
    }
    else
    {
      std::cout << "result = " << result << " - object not callable";
    }
2. Trying to call a C++ method from wxPython that passes a list of string
from C++ to wxPython

The following method generate errors when called in wxPython

static PyObject* passAListOfString(PyObject *self, PyObject *args)
{
  //create a PyObject*
  char* myItems[2];
  myItems[0] = "1 LOG FROM C++";
  myItems[1] = "2 SECOND LOG FROM C++";
  PyObject* items = Py_BuildValue("[items]", myItems[0], myItems[1]);
    return items;
}

Note that the following method works fine:

static PyObject* passAListOfString(PyObject *self, PyObject *args)
{
  PyObject* items = Py_BuildValue("s", "1 LOG FROM C++");
      return items;
}

#This is called in wxPython like this:
items = passAListOfString()
#I then call
refreshLogList(self,items)

Thanks for your help

Cedric

Cedric wrote:

Dear All,

I would like to refresh a list of log entry messages (= a list of string)
that is displayed in a wxPython GUI from a C++ application.

Have you looked at the wxPython embedding sample? While it doesn't do exactly what you need it should at least put you on the right track.

1. I first tryed to import a C++ method in wxPython to set a pointer on a
refreshGUI method defined in the Python script
Problem: the pointer on the wxPython method is not callable
2. I then tryed to import a C++ method in wxPython that processes the
refresh
Problem: I cannot pass a list of string to wxPython. I do not know how to
use Py_BuildValue to pass a list of string.

Details of the tries:

1. Trying to call a wxPython method from C++
1.1. I first defined the following method in the wxPython script:

   def refreshLogList(self,items):
  self.LogList.Clear()
  self.LogList.InsertItems(items,0)

The following syntax works fine from within the wxPython script:

  items = ("1 First Log Message",
           "2 Second Log Message")
  self.refreshLogList(items)

1.2. I then tryed to call the method refreshLogList from C++
I defined a method in C++ to get a pointer on the refreshLogList method:
static PyObject* setGUI_RefreshPointer(PyObject *self, PyObject *args)
{
  //Here I try to extract the pointer from args using PyArg_ParseTuple and
store it in a local C++ variable declared like this: "static PyObject*
myGUI_RefreshPointer"

Which format code did you use in the call to PyArg_ParseTuple? I think it should be "O".

}

In the wxPython script I call setGUI_RefreshPointer(refreshLogList)

=> this all seems to work correctly and running my C++ application step by
step, I get a pointer address in myGUIPointer.

The problem is that that pointer is not callable.

Did you increment the object's reference count? If not then it may have been garbarge collected and no longet exist any longer.

2. Trying to call a C++ method from wxPython that passes a list of string
from C++ to wxPython

The following method generate errors when called in wxPython

static PyObject* passAListOfString(PyObject *self, PyObject *args)
{
  //create a PyObject*
  char* myItems[2];
  myItems[0] = "1 LOG FROM C++";
  myItems[1] = "2 SECOND LOG FROM C++";
  PyObject* items = Py_BuildValue("[items]", myItems[0], myItems[1]);
    return items;
}

You can't use Py_BuildValue to make a list. You'll need to drop down a level in the Python C API and build the list step by step using PyList_New(), creating PyObjects from your item values and adding them to the list with PyList_Append. Be careful about the refcounts.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn wrote:

You can't use Py_BuildValue to make a list. You'll need to drop down a level in the Python C API and build the list step by step using PyList_New(), creating PyObjects from your item values and adding them to the list with PyList_Append. Be careful about the refcounts.

And you might want to look at Boost.Python to help with all that.

http://www.boost.org/libs/python/doc/index.html

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer
                                         
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov