Embedding PyQt4 into an Application running Python via Boost::Python
Hi,
first of all, i hope i chose the right forum, but it thought i am having "installation" problems, so i might be right here.
I'm developing an Application (which is Qt based itself) .. with Python integration using boost::python.
At first i want to mention that i don't have any problems running PyQt4 code using my native python interpreter /somewhere/Python26/Python.exe
Now i try to have my script sourrounding understand pyqt4 so scripts can take usage of it. Unfortunatly i am getting
Quote:
ImportError: DLL load failed: The specified procedure could not be found.
errors when i try to run python code like
Code:
from PyQt4 import QtGui
.
or
Code:
from PyQt4 import *
will pass without any errors, but not giving me access to anything inside the Module.
I spent a few hours on investigation by now and couldn't find anything related so far, the most issues about PyQt + embedding are about sharing objects, not about the installation process itself.
I guess i miss some setup required for my runtime python interpreter to know where to look for the dlls or something similar.
My current application folder setup is like this:
- Application.exe
- boost_python-vc90-mt-1_41.dll
- python26.dll
- QtCore4.dll
- QtGui4.dll
- Qt.pyd
- QtCore.pyd
- QtGui.pyd
- TestFile.txt
I successfully read the TestFile.txt by reading "./TestFile.txt" via Python ... so the base path of the interpreter should find those modules as well?
I also tried placing all *.pyd files from my PyQt4 installation inside the application folder to be sure its not a problem because the qt system is not complete.
I've no idea how to get PyQt working inside my application and would be very grateful for any hint that might get me into the right direction.
Thanks
Gunnar
Re: Embedding PyQt4 into an Application running Python via Boost::Python
This is an example how to integrate PyQt4 and boost::python
first of all we must define wrap/unwrap function to deal with bare pointers
Code:
return reinterpret_cast<long int>(ptr);
}
template <typename T>
T* wrap(long int ptr) {
return reinterpret_cast<T*>(ptr);
}
after that we must register all classes we want integrate to
Code:
class_<QObject,
QObject*, boost
::noncopyable>
("QObject", no_init
) .def("unwrap", unwrap)
.def("wrap", make_function( wrap<QObject>, return_value_policy<return_by_value>() ))
.staticmethod("wrap");
class_<QWidget, bases<QObject>,
QWidget*, boost
::noncopyable>
("QWidget") .def("wrap", make_function( wrap<QWidget>, return_value_policy<return_by_value>() ))
.staticmethod("wrap");
class_<QFrame, bases<QWidget>,
QFrame*, boost
::noncopyable>
("QFrame") .def("wrap", make_function( wrap<QFrame>, return_value_policy<return_by_value>() ))
.staticmethod("wrap");
class_<QLabel, bases<QFrame>,
QLabel*, boost
::noncopyable>
("QLabel") .def("wrap", make_function( wrap<QLabel>, return_value_policy<return_by_value>() ))
.staticmethod("wrap");
and for example we have class that works with.. QLabel:
we must expose this class to python too:
Code:
class_<worker, bases<QObject>, worker*, boost::noncopyable>("worker")
.def("add_label", &worker::add_label);
now we a ready to interaction,
on C++-size do something like this
Code:
worker* w = new worker;
main_namespace["worker"] = boost::ref(w);
python:
Code:
from PyQt4.Qt import *
import sip
import mylib as MyLib
#...
#If you are using QApplication on C++-size you don't need to create another one
lb
= QLabel("label from PyQt4!")
lb_ptr = sip.unwrapinstance(f)
my_lb
= MyLib.
QLabel.
wrap(lb_ptr
)
worker.add_label(my_lb)
In other case if you wan't send you own Q-object to PyQt4 :
Code:
main_namespace["lb"] = boost::ref(lb);
python:
Code:
from PyQt4.Qt import *
import sip
import mylib as MyLib
#...
my_lb_ptr = lb.unwrap()
qt_lb
= sip.
wrapinstance(my_lb_ptr,
QLabel)
And this is my real little helper:
Code:
from PyQt4.Qt import *
import sip
def toQt(object, type):
ptr = object.unwrap()
return sip.wrapinstance(ptr, type)
def fromQt(object, type):
ptr = sip.unwrapinstance(object)
return type.wrap(ptr)