@@ -5,7 +5,7 florianlink | 2008-09-01 | |||||
5 | - merged in features/fixes from the MeVisLab repository: |
|
5 | - merged in features/fixes from the MeVisLab repository: | |
6 | - added createModuleFromFile/createModuleFromScript/createUniqueModule |
|
6 | - added createModuleFromFile/createModuleFromScript/createUniqueModule | |
7 | - switched object destruction to use QPointer and lazy wrapper removal to avoid expensive objectDestroyed signal connections |
|
7 | - switched object destruction to use QPointer and lazy wrapper removal to avoid expensive objectDestroyed signal connections | |
8 | - added hash() support for PythnQtWrapper object |
|
8 | - added hash() support for PythonQtWrapper object | |
9 | - added support for signal to python function connections where the function has less arguments than the emitted signal |
|
9 | - added support for signal to python function connections where the function has less arguments than the emitted signal | |
10 | - added setQObject[NoLonger]WrappedCallback API to support external reference counting on QObjects that are exposed to PythonQt |
|
10 | - added setQObject[NoLonger]WrappedCallback API to support external reference counting on QObjects that are exposed to PythonQt | |
11 | - implemented flush on std redirect to support python logging framework |
|
11 | - implemented flush on std redirect to support python logging framework |
@@ -8,11 +8,13 int main (int argc, char* argv[]) { | |||||
8 | { |
|
8 | { | |
9 | // evaluate a python file embedded in executable as resource: |
|
9 | // evaluate a python file embedded in executable as resource: | |
10 | mainModule.evalFile(":eyed3tagger.py"); |
|
10 | mainModule.evalFile(":eyed3tagger.py"); | |
|
11 | // create an object, hold onto its reference | |||
11 | PythonQtObjectPtr tag = mainModule.evalScript("EyeD3Tagger()\n", Py_eval_input); |
|
12 | PythonQtObjectPtr tag = mainModule.evalScript("EyeD3Tagger()\n", Py_eval_input); | |
12 | Q_ASSERT(!tag.isNull()); |
|
13 | Q_ASSERT(!tag.isNull()); | |
13 | tag.call("setFileName", QVariantList() << "t.mp3"); |
|
14 | tag.call("setFileName", QVariantList() << "t.mp3"); | |
14 | QVariant fn = tag.call("fileName", QVariantList()); |
|
15 | QVariant fn = tag.call("fileName", QVariantList()); | |
15 | Q_ASSERT(fn.toString() == QString("t.mp3")); |
|
16 | Q_ASSERT(fn.toString() == QString("t.mp3")); | |
|
17 | // tag goes out of scope, reference count decremented. | |||
16 | } |
|
18 | } | |
17 | qDebug() << "test1"; |
|
19 | qDebug() << "test1"; | |
18 | { // alternative using import and loading it as a real module from sys.path |
|
20 | { // alternative using import and loading it as a real module from sys.path | |
@@ -20,7 +22,6 int main (int argc, char* argv[]) { | |||||
20 | mainModule.evalScript(QString("import sys\n")); |
|
22 | mainModule.evalScript(QString("import sys\n")); | |
21 | // append the current directory to the sys.path |
|
23 | // append the current directory to the sys.path | |
22 | mainModule.evalScript(QString("sys.path.append('%1')\n").arg(QDir::currentPath())); |
|
24 | mainModule.evalScript(QString("sys.path.append('%1')\n").arg(QDir::currentPath())); | |
23 |
|
||||
24 | mainModule.evalScript("import eyed3tagger\n"); |
|
25 | mainModule.evalScript("import eyed3tagger\n"); | |
25 | PythonQtObjectPtr tag = mainModule.evalScript("eyed3tagger.EyeD3Tagger()\n", Py_eval_input); |
|
26 | PythonQtObjectPtr tag = mainModule.evalScript("eyed3tagger.EyeD3Tagger()\n", Py_eval_input); | |
26 | Q_ASSERT(!tag.isNull()); |
|
27 | Q_ASSERT(!tag.isNull()); |
@@ -1,9 +1,7 | |||||
1 |
|
|
1 | This example shows how to add user defined Python classes | |
2 | embedded Python mainModule. |
|
2 | to the embedded Python mainModule. | |
|
3 | ||||
3 | It also shows how to create objects in Python, |
|
4 | It also shows how to create objects in Python, | |
4 | hold onto reference counted smart pointers to them from |
|
5 | hold onto reference counted smart pointers to them from | |
5 | a Qt application, and invoke methods on them via |
|
6 | a Qt application, and invoke methods on them via | |
6 | the PythonQtObjectPtr interface. |
|
7 | the PythonQtObjectPtr interface. | |
7 |
|
||||
8 |
|
||||
9 |
|
@@ -24,3 +24,4 box.edit.connect('returnPressed()', appendLine) | |||||
24 |
|
24 | |||
25 | # show the window |
|
25 | # show the window | |
26 | box.show() |
|
26 | box.show() | |
|
27 |
@@ -60,6 +60,15 int main( int argc, char **argv ) | |||||
60 | // evaluate a simple python script and receive the result a qvariant: |
|
60 | // evaluate a simple python script and receive the result a qvariant: | |
61 | QVariant result = mainModule.evalScript("19*2+4", Py_eval_input); |
|
61 | QVariant result = mainModule.evalScript("19*2+4", Py_eval_input); | |
62 |
|
62 | |||
|
63 | // Create object from python, hold onto reference in C++: | |||
|
64 | PythonQtObjectPtr tag = mainModule.evalScript("EyeD3Tagger()\n", Py_eval_input); | |||
|
65 | Q_ASSERT(!tag.isNull()); | |||
|
66 | ||||
|
67 | // call python methods from C++ | |||
|
68 | tag.call("setFileName", QVariantList() << "t.mp3"); | |||
|
69 | QVariant fn = tag.call("fileName", QVariantList()); | |||
|
70 | Q_ASSERT(fn.toString() == QString("t.mp3")); | |||
|
71 | ||||
63 | // create a small Qt GUI |
|
72 | // create a small Qt GUI | |
64 | QVBoxLayout* vbox = new QVBoxLayout; |
|
73 | QVBoxLayout* vbox = new QVBoxLayout; | |
65 | QGroupBox* box = new QGroupBox; |
|
74 | QGroupBox* box = new QGroupBox; | |
@@ -85,6 +94,8 int main( int argc, char **argv ) | |||||
85 | // shows how to call the method with a text that will be append to the browser |
|
94 | // shows how to call the method with a text that will be append to the browser | |
86 | mainModule.call("appendText", QVariantList() << "The ultimate answer is "); |
|
95 | mainModule.call("appendText", QVariantList() << "The ultimate answer is "); | |
87 |
|
96 | |||
|
97 | ||||
|
98 | ||||
88 |
|
|
99 | return qapp.exec(); | |
89 | } |
|
100 | } | |
90 |
|
101 |
@@ -52,17 +52,18 | |||||
52 | \section Introduction |
|
52 | \section Introduction | |
53 |
|
53 | |||
54 | \b PythonQt is a dynamic Python (http://www.python.org) binding for Qt (http://www.trolltech.com). |
|
54 | \b PythonQt is a dynamic Python (http://www.python.org) binding for Qt (http://www.trolltech.com). | |
55 |
It offers an easy way to embed |
|
55 | It offers an easy way to embed the Python scripting language into | |
56 | your Qt applications. It makes heavy use of the QMetaObject system and thus requires Qt4.x. |
|
56 | your Qt applications. It makes heavy use of the QMetaObject system and thus requires Qt4.x. | |
57 |
|
57 | |||
58 | In contrast to <a href="http://www.riverbankcomputing.co.uk/pyqt/">PyQt</a> , PythonQt is \b not a complete |
|
58 | In contrast to <a href="http://www.riverbankcomputing.co.uk/pyqt/">PyQt</a> , PythonQt is \b not a complete | |
59 | Python wrapper around the complete Qt functionality. So if you are looking for a way to |
|
59 | Python wrapper around the complete Qt functionality. So if you are looking for a way to | |
60 | write complete applications in Python using the Qt GUI, you should use PyQt. |
|
60 | write complete applications in Python using the Qt GUI, you should use PyQt. | |
61 |
|
61 | |||
62 |
If you are looking for a simple way to embed |
|
62 | If you are looking for a simple way to embed Python objects into your C++/Qt Application | |
63 | and to script parts of your application via Python, PythonQt is the way to go! |
|
63 | and to script parts of your application via Python, PythonQt is the way to go! | |
64 |
|
64 | |||
65 |
PythonQt is a stable library that was developed to make the |
|
65 | PythonQt is a stable library that was developed to make the | |
|
66 | Image Processing and Visualization platform MeVisLab (http://www.mevislab.de) | |||
66 | scriptable from Python. |
|
67 | scriptable from Python. | |
67 |
|
68 | |||
68 | \section Licensing |
|
69 | \section Licensing | |
@@ -76,12 +77,14 | |||||
76 |
|
77 | |||
77 | \section Features |
|
78 | \section Features | |
78 |
|
79 | |||
|
80 | - Easy wrapping of Python objects from C++ with smart, reference-counting PythonQtObjectPtr. | |||
|
81 | - Convenient conversions to/from QVariant for PythonQtObjectPtr. | |||
79 | - Access all \b slots, \b properties, children and registered enums of any QObject derived class from Python |
|
82 | - Access all \b slots, \b properties, children and registered enums of any QObject derived class from Python | |
80 | - Connecting Qt Signals to Python functions (both from within Python and from C++) |
|
83 | - Connecting Qt Signals to Python functions (both from within Python and from C++) | |
81 |
- Wrapping of C++ objects (which are not derived from QObject) via PythonQtC |
|
84 | - Wrapping of C++ objects (which are not derived from QObject) via PythonQtCppWrapperFactory | |
82 | - Extending C++ and QObject derived classes with additional slots, static methods and constructors (see Decorators) |
|
85 | - Extending C++ and QObject derived classes with additional slots, static methods and constructors (see Decorators) | |
83 | - StdOut/Err redirection to Qt signals instead of cout |
|
86 | - StdOut/Err redirection to Qt signals instead of cout | |
84 | - Interface for creating your own \c import replacement, so that Python scripts can be e.g. signed/verified before they are executed (PythonQtImportInterface) |
|
87 | - Interface for creating your own \c import replacement, so that Python scripts can be e.g. signed/verified before they are executed (PythonQtImportFileInterface) | |
85 | - Mapping of plain-old-datatypes and ALL QVariant types to and from Python |
|
88 | - Mapping of plain-old-datatypes and ALL QVariant types to and from Python | |
86 | - Support for wrapping of user QVariant types which are registerd via QMetaType |
|
89 | - Support for wrapping of user QVariant types which are registerd via QMetaType | |
87 | - Support for Qt namespace (with all enumerators) |
|
90 | - Support for Qt namespace (with all enumerators) | |
@@ -93,7 +96,7 | |||||
93 | Features that PythonQt does NOT support (and will not support): |
|
96 | Features that PythonQt does NOT support (and will not support): | |
94 |
|
97 | |||
95 | - you can not derive from QObjects inside of Python, this would require wrapper generation like PyQt does |
|
98 | - you can not derive from QObjects inside of Python, this would require wrapper generation like PyQt does | |
96 |
- you can only script QObject derived classes, for normal C++ classes you need to create a PythonQtC |
|
99 | - 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 | |
97 | - 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 |
|
100 | - 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 | |
98 |
|
101 | |||
99 | \section Interface |
|
102 | \section Interface | |
@@ -127,7 +130,7 | |||||
127 | <tr><td>OwnRegisteredMetaType</td><td>variant wrapper, optionally with a wrapper provided by addVariantWrapper()</td></tr> |
|
130 | <tr><td>OwnRegisteredMetaType</td><td>variant wrapper, optionally with a wrapper provided by addVariantWrapper()</td></tr> | |
128 | <tr><td>EnumType</td><td>integer (all enums that are known via the moc and the Qt namespace are supported)</td></tr> |
|
131 | <tr><td>EnumType</td><td>integer (all enums that are known via the moc and the Qt namespace are supported)</td></tr> | |
129 | <tr><td>QObject (and derived classes)</td><td>QObject wrapper</td></tr> |
|
132 | <tr><td>QObject (and derived classes)</td><td>QObject wrapper</td></tr> | |
130 |
<tr><td>C++ object</td><td>CPP wrapper, either wrapped via PythonQtC |
|
133 | <tr><td>C++ object</td><td>CPP wrapper, either wrapped via PythonQtCppWrapperFactory or just decorated with decorators</td></tr> | |
131 | <tr><td>PyObject</td><td>PyObject</td></tr> |
|
134 | <tr><td>PyObject</td><td>PyObject</td></tr> | |
132 | </table> |
|
135 | </table> | |
133 |
|
136 | |||
@@ -182,8 +185,9 | |||||
182 |
|
185 | |||
183 | \section CPP CPP Wrapping |
|
186 | \section CPP CPP Wrapping | |
184 |
|
187 | |||
185 |
You can create dedicated wrapper QObject for any C++ class. This is done by deriving from PythonQtC |
|
188 | You can create dedicated wrapper QObject for any C++ class. This is done by deriving from PythonQtCppWrapperFactory | |
186 | and adding your factory via addWrapperFactory(). Whenever PythonQt encounters a CPP pointer (e.g. on a slot or signal) |
|
189 | and adding your factory via addWrapperFactory(). | |
|
190 | Whenever PythonQt encounters a CPP pointer (e.g. on a slot or signal) | |||
187 | and it does not known it as a QObject derived class, it will create a generic CPP wrapper. So even unknown C++ objects |
|
191 | and it does not known it as a QObject derived class, it will create a generic CPP wrapper. So even unknown C++ objects | |
188 | can be passed through Python. If the wrapper factory supports the CPP class, a QObject wrapper will be created for each |
|
192 | can be passed through Python. If the wrapper factory supports the CPP class, a QObject wrapper will be created for each | |
189 | instance that enters Python. An alternative to a complete wrapper via the wrapper factory are decorators, see \ref Decorators |
|
193 | instance that enters Python. An alternative to a complete wrapper via the wrapper factory are decorators, see \ref Decorators |
@@ -46,7 +46,8 | |||||
46 | #include <QString> |
|
46 | #include <QString> | |
47 | #include <QByteArray> |
|
47 | #include <QByteArray> | |
48 |
|
48 | |||
49 |
//! |
|
49 | //! Defines an abstract interface to file access for the Python import statement. | |
|
50 | //! see PythonQt::setImporter() | |||
50 | class PythonQtImportFileInterface { |
|
51 | class PythonQtImportFileInterface { | |
51 |
|
52 | |||
52 | public: |
|
53 | public: |
General Comments 0
You need to be logged in to leave comments.
Login now