diff --git a/CHANGELOG.txt b/CHANGELOG.txt index e4d0f37..6b3bc71 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -5,7 +5,7 @@ florianlink | 2008-09-01 - merged in features/fixes from the MeVisLab repository: - added createModuleFromFile/createModuleFromScript/createUniqueModule - switched object destruction to use QPointer and lazy wrapper removal to avoid expensive objectDestroyed signal connections -- added hash() support for PythnQtWrapper object +- added hash() support for PythonQtWrapper object - added support for signal to python function connections where the function has less arguments than the emitted signal - added setQObject[NoLonger]WrappedCallback API to support external reference counting on QObjects that are exposed to PythonQt - implemented flush on std redirect to support python logging framework diff --git a/examples/CPPPyWrapperExample/CPPPyWrapperExample.cpp b/examples/CPPPyWrapperExample/CPPPyWrapperExample.cpp index d4e0934..aed81f0 100644 --- a/examples/CPPPyWrapperExample/CPPPyWrapperExample.cpp +++ b/examples/CPPPyWrapperExample/CPPPyWrapperExample.cpp @@ -8,11 +8,13 @@ int main (int argc, char* argv[]) { { // evaluate a python file embedded in executable as resource: mainModule.evalFile(":eyed3tagger.py"); + // create an object, hold onto its reference PythonQtObjectPtr tag = mainModule.evalScript("EyeD3Tagger()\n", Py_eval_input); Q_ASSERT(!tag.isNull()); tag.call("setFileName", QVariantList() << "t.mp3"); QVariant fn = tag.call("fileName", QVariantList()); Q_ASSERT(fn.toString() == QString("t.mp3")); + // tag goes out of scope, reference count decremented. } qDebug() << "test1"; { // alternative using import and loading it as a real module from sys.path @@ -20,7 +22,6 @@ int main (int argc, char* argv[]) { mainModule.evalScript(QString("import sys\n")); // append the current directory to the sys.path mainModule.evalScript(QString("sys.path.append('%1')\n").arg(QDir::currentPath())); - mainModule.evalScript("import eyed3tagger\n"); PythonQtObjectPtr tag = mainModule.evalScript("eyed3tagger.EyeD3Tagger()\n", Py_eval_input); Q_ASSERT(!tag.isNull()); diff --git a/examples/CPPPyWrapperExample/README.txt b/examples/CPPPyWrapperExample/README.txt index 4b5ba69..41de293 100644 --- a/examples/CPPPyWrapperExample/README.txt +++ b/examples/CPPPyWrapperExample/README.txt @@ -1,9 +1,7 @@ -It also shows how to add user defined Python classes to the -embedded Python mainModule. +This example shows how to add user defined Python classes +to the embedded Python mainModule. + It also shows how to create objects in Python, hold onto reference counted smart pointers to them from a Qt application, and invoke methods on them via the PythonQtObjectPtr interface. - - - diff --git a/examples/PyGettingStarted/GettingStarted.py b/examples/PyGettingStarted/GettingStarted.py index 597b23a..ff88dcb 100644 --- a/examples/PyGettingStarted/GettingStarted.py +++ b/examples/PyGettingStarted/GettingStarted.py @@ -24,3 +24,4 @@ box.edit.connect('returnPressed()', appendLine) # show the window box.show() + diff --git a/examples/PyGettingStarted/main.cpp b/examples/PyGettingStarted/main.cpp index 1aa0adc..11d1fad 100644 --- a/examples/PyGettingStarted/main.cpp +++ b/examples/PyGettingStarted/main.cpp @@ -60,6 +60,15 @@ int main( int argc, char **argv ) // evaluate a simple python script and receive the result a qvariant: QVariant result = mainModule.evalScript("19*2+4", Py_eval_input); + // Create object from python, hold onto reference in C++: + PythonQtObjectPtr tag = mainModule.evalScript("EyeD3Tagger()\n", Py_eval_input); + Q_ASSERT(!tag.isNull()); + + // call python methods from C++ + tag.call("setFileName", QVariantList() << "t.mp3"); + QVariant fn = tag.call("fileName", QVariantList()); + Q_ASSERT(fn.toString() == QString("t.mp3")); + // create a small Qt GUI QVBoxLayout* vbox = new QVBoxLayout; QGroupBox* box = new QGroupBox; @@ -85,6 +94,8 @@ int main( int argc, char **argv ) // shows how to call the method with a text that will be append to the browser mainModule.call("appendText", QVariantList() << "The ultimate answer is "); + + return qapp.exec(); } diff --git a/src/PythonQtDoc.h b/src/PythonQtDoc.h index c715efc..48188ba 100644 --- a/src/PythonQtDoc.h +++ b/src/PythonQtDoc.h @@ -52,17 +52,18 @@ \section Introduction \b PythonQt is a dynamic Python (http://www.python.org) binding for Qt (http://www.trolltech.com). - It offers an easy way to embedd the Python scripting language into + It offers an easy way to embed the Python scripting language into your Qt applications. It makes heavy use of the QMetaObject system and thus requires Qt4.x. In contrast to PyQt , PythonQt is \b not a complete Python wrapper around the complete Qt functionality. So if you are looking for a way to write complete applications in Python using the Qt GUI, you should use PyQt. - If you are looking for a simple way to embed the Python language into your Qt Application - and to script parts of your application via Python, PythonQt is the way to go! + If you are looking for a simple way to embed Python objects into your C++/Qt Application + and to script parts of your application via Python, PythonQt is the way to go! - PythonQt is a stable library that was developed to make the Image Processing and Visualization platform MeVisLab (http://www.mevislab.de) + PythonQt is a stable library that was developed to make the + Image Processing and Visualization platform MeVisLab (http://www.mevislab.de) scriptable from Python. \section Licensing @@ -76,12 +77,14 @@ \section Features + - Easy wrapping of Python objects from C++ with smart, reference-counting PythonQtObjectPtr. + - Convenient conversions to/from QVariant for PythonQtObjectPtr. - Access all \b slots, \b properties, children and registered enums of any QObject derived class from Python - Connecting Qt Signals to Python functions (both from within Python and from C++) - - Wrapping of C++ objects (which are not derived from QObject) via PythonQtCPPWrapperFactory + - Wrapping of C++ objects (which are not derived from QObject) via PythonQtCppWrapperFactory - Extending C++ and QObject derived classes with additional slots, static methods and constructors (see Decorators) - StdOut/Err redirection to Qt signals instead of cout - - Interface for creating your own \c import replacement, so that Python scripts can be e.g. signed/verified before they are executed (PythonQtImportInterface) + - Interface for creating your own \c import replacement, so that Python scripts can be e.g. signed/verified before they are executed (PythonQtImportFileInterface) - Mapping of plain-old-datatypes and ALL QVariant types to and from Python - Support for wrapping of user QVariant types which are registerd via QMetaType - Support for Qt namespace (with all enumerators) @@ -93,7 +96,7 @@ Features that PythonQt does NOT support (and will not support): - you can not derive from QObjects inside of Python, this would require wrapper generation like PyQt does - - you can only script QObject derived classes, for normal C++ classes you need to create a PythonQtCPPWrapperFactory and adequate wrapper classes or add decorator slots + - you can only script QObject derived classes, for normal C++ classes you need to create a PythonQtCppWrapperFactory and adequate wrapper classes or add decorator slots - you can not access normal member functions of QObjects, only slots and properties, because the \b moc does not store normal member functions in the MetaObject system \section Interface @@ -127,7 +130,7 @@ OwnRegisteredMetaTypevariant wrapper, optionally with a wrapper provided by addVariantWrapper() EnumTypeinteger (all enums that are known via the moc and the Qt namespace are supported) QObject (and derived classes)QObject wrapper - C++ objectCPP wrapper, either wrapped via PythonQtCPPWrapperFactory or just decorated with decorators + C++ objectCPP wrapper, either wrapped via PythonQtCppWrapperFactory or just decorated with decorators PyObjectPyObject @@ -182,8 +185,9 @@ \section CPP CPP Wrapping -You can create dedicated wrapper QObject for any C++ class. This is done by deriving from PythonQtCPPWrapperFactory -and adding your factory via addWrapperFactory(). Whenever PythonQt encounters a CPP pointer (e.g. on a slot or signal) +You can create dedicated wrapper QObject for any C++ class. This is done by deriving from PythonQtCppWrapperFactory +and adding your factory via addWrapperFactory(). +Whenever PythonQt encounters a CPP pointer (e.g. on a slot or signal) and it does not known it as a QObject derived class, it will create a generic CPP wrapper. So even unknown C++ objects can be passed through Python. If the wrapper factory supports the CPP class, a QObject wrapper will be created for each instance that enters Python. An alternative to a complete wrapper via the wrapper factory are decorators, see \ref Decorators diff --git a/src/PythonQtImportFileInterface.h b/src/PythonQtImportFileInterface.h index cfd98f5..53a22f3 100644 --- a/src/PythonQtImportFileInterface.h +++ b/src/PythonQtImportFileInterface.h @@ -46,7 +46,8 @@ #include #include -//! defines an abstract interface to file access for the Python import statement +//! Defines an abstract interface to file access for the Python import statement. +//! see PythonQt::setImporter() class PythonQtImportFileInterface { public: