[PyQt] Fwd: Re: c++ app integrate PyQt

Matt Newell newellm at blur.com
Tue Oct 1 19:52:25 BST 2013


> 
> That sounds encouraging.  But it lacks a little detail - like how does
> one embed python (PyQt) into a C++ app.  The sip I sort of understand
> and it is doable.  I only need a few C++ classes and that makes sense.
> But I don't have a clue how or where to start on embeding PyQt.  Does
> someone have an example or a link explaining the details.
> 
> Johnf

The embedding is really not very involved.  Here is a snippet of code from one 
of my apps, with some irrelevant stuff removed.  This both initializes python, 
and loads CWD/plugins as a python module where you can load whatever you want 
from the __init__.py, including submodules.

Matt

// Return the named attribute object from the named module.
// Returns a NEW reference(PyObject_GetAttrString)
PyObject * getModuleAttr(const char *module, const char *attr)
{
#if PY_VERSION_HEX >= 0x02050000
    PyObject *mod = PyImport_ImportModule(module);
#else
    PyObject *mod = PyImport_ImportModule(const_cast<char *>(module));
#endif

    if (!mod)
    {
        PyErr_Print();
        return 0;
    }

#if PY_VERSION_HEX >= 0x02050000
    PyObject *obj = PyObject_GetAttrString(mod, attr);
#else
    PyObject *obj = PyObject_GetAttrString(mod, const_cast<char *>(attr));
#endif

    Py_DECREF(mod);

    if (!obj)
    {
        PyErr_Print();
        return 0;
    }

    return obj;
}

void loadPythonPlugins()
{
	
	Py_Initialize();
	PyEval_InitThreads();
	
	PyObject * sys_path = getModuleAttr("sys", "path");

	if (!sys_path) {
		LOG_1( "Python Initialization Failure: Failed to get sys.path" );
		return;
	}
	
	QString dir = QDir::currentPath();
	
	// Convert the directory to a Python object with native separators.
#if QT_VERSION >= 0x040200
	dir = QDir::toNativeSeparators(dir);
#else
	dir = QDir::convertSeparators(dir);
#endif

#if PY_MAJOR_VERSION >= 3
	// This is a copy of qpycore_PyObject_FromQString().

	PyObject *dobj = PyUnicode_FromUnicode(0, dir.length());

	if (!dobj)
	{
		PyErr_Print();
		return;
	}

	Py_UNICODE *pyu = PyUnicode_AS_UNICODE(dobj);

	for (int i = 0; i < dir.length(); ++i)
		*pyu++ = dir.at(i).unicode();
#else
	PyObject *dobj = PyString_FromString(dir.toAscii().constData());

	if (!dobj)
	{
		PyErr_Print();
		return;
	}
#endif

	// Add the directory to sys.path.
	int rc = PyList_Append(sys_path, dobj);
	Py_DECREF(dobj);
	Py_DECREF(sys_path);
	
	if (rc < 0)
	{
		PyErr_Print();
		return;
	}

	PyObject *plug_mod = PyImport_ImportModule("plugins");
	if (!plug_mod)
	{
		PyErr_Print();
		return;
	}
	Py_DECREF(plug_mod);
	
	PyEval_SaveThread();
}


More information about the PyQt mailing list