##// END OF EJS Templates
improved docs...
florianlink -
r147:83df95056589
parent child
Show More
@@ -1,522 +1,525
1 #ifndef _PYTHONQTDOC_H
1 #ifndef _PYTHONQTDOC_H
2 #define _PYTHONQTDOC_H
2 #define _PYTHONQTDOC_H
3
3
4 /*
4 /*
5 *
5 *
6 * Copyright (C) 2010 MeVis Medical Solutions AG All Rights Reserved.
6 * Copyright (C) 2010 MeVis Medical Solutions AG All Rights Reserved.
7 *
7 *
8 * This library is free software; you can redistribute it and/or
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
11 * version 2.1 of the License, or (at your option) any later version.
12 *
12 *
13 * This library is distributed in the hope that it will be useful,
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
16 * Lesser General Public License for more details.
17 *
17 *
18 * Further, this software is distributed without any warranty that it is
18 * Further, this software is distributed without any warranty that it is
19 * free of the rightful claim of any third person regarding infringement
19 * free of the rightful claim of any third person regarding infringement
20 * or the like. Any license provided herein, whether implied or
20 * or the like. Any license provided herein, whether implied or
21 * otherwise, applies only to this software file. Patent licenses, if
21 * otherwise, applies only to this software file. Patent licenses, if
22 * any, provided herein do not apply to combinations of this program with
22 * any, provided herein do not apply to combinations of this program with
23 * other software, or any other product whatsoever.
23 * other software, or any other product whatsoever.
24 *
24 *
25 * You should have received a copy of the GNU Lesser General Public
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
28 *
29 * Contact information: MeVis Medical Solutions AG, Universitaetsallee 29,
29 * Contact information: MeVis Medical Solutions AG, Universitaetsallee 29,
30 * 28359 Bremen, Germany or:
30 * 28359 Bremen, Germany or:
31 *
31 *
32 * http://www.mevis.de
32 * http://www.mevis.de
33 *
33 *
34 */
34 */
35
35
36 //----------------------------------------------------------------------------------
36 //----------------------------------------------------------------------------------
37 /*!
37 /*!
38 // \file PythonQtDoc.h
38 // \file PythonQtDoc.h
39 // \author Florian Link
39 // \author Florian Link
40 // \author Last changed by $Author: florian $
40 // \author Last changed by $Author: florian $
41 // \date 2006-10
41 // \date 2006-10
42 */
42 */
43 //----------------------------------------------------------------------------------
43 //----------------------------------------------------------------------------------
44
44
45 /*!
45 /*!
46 \if USE_GLOBAL_DOXYGEN_DOC
46 \if USE_GLOBAL_DOXYGEN_DOC
47 \page PythonQtPage PythonQt Overview
47 \page PythonQtPage PythonQt Overview
48 \else
48 \else
49 \mainpage notitle
49 \mainpage notitle
50 \endif
50 \endif
51
51
52 \image html PythonQt.jpg
52 \image html PythonQt.jpg
53
53
54 \section Introduction
54 \section Introduction
55
55
56 \b PythonQt is a dynamic Python (http://www.python.org) binding for the Qt framework (http://qt.nokia.com).
56 \b PythonQt is a dynamic <a href="http://www.python.org" target="_blank">
57 Python</a> binding for the <a href="http://qt.nokia.com" target="_blank">
58 Qt framework</a>.
57 It offers an easy way to embed the Python scripting language into
59 It offers an easy way to embed the Python scripting language into
58 your C++ Qt applications. It makes heavy use of the QMetaObject system and thus requires Qt 4.x.
60 your C++ Qt applications. It makes heavy use of the QMetaObject system and thus requires Qt 4.x.
59
61
60 The focus of PythonQt is on embedding Python into an existing C++ application, not on writing the whole
62 The focus of PythonQt is on embedding Python into an existing C++ application, not on writing the whole
61 application completely in Python. If you want to write your whole application in Python,
63 application completely in Python. If you want to write your whole application in Python,
62 you should use <a href="http://www.riverbankcomputing.co.uk/pyqt/">PyQt</a> or <a href="http://www.pyside.org">PySide</a> instead.
64 you should use <a href="http://www.riverbankcomputing.co.uk/pyqt/" target="_blank">PyQt</a> or <a href="http://www.pyside.org" target="_blank">PySide</a> instead.
63
65
64 If you are looking for a simple way to embed Python objects into your C++/Qt Application
66 If you are looking for a simple way to embed Python objects into your C++/Qt Application
65 and to script parts of your application via Python, PythonQt is the way to go!
67 and to script parts of your application via Python, PythonQt is the way to go!
66
68
67 PythonQt is a stable library that was developed to make the
69 PythonQt is a stable library that was developed to make the
68 Image Processing and Visualization platform MeVisLab (http://www.mevislab.de)
70 Image Processing and Visualization platform <a href="http://www.mevislab.de" target="_blank">MeVisLab</a>
69 scriptable from Python.
71 scriptable from Python.
70
72
71 \page Features Features
73 \page Features Features
72
74
73 \section Builtin Built-in Features
75 \section Builtin Built-in Features
74
76
75 The following are the built-in features of the PythonQt library:
77 The following are the built-in features of the PythonQt library:
76
78
77 - Access all \b slots, \b properties, children and registered enums of any QObject derived class from Python
79 - Access all \b slots, \b properties, children and registered enums of any QObject derived class from Python
78 - Connecting Qt Signals to Python functions (both from within Python and from C++)
80 - Connecting Qt Signals to Python functions (both from within Python and from C++)
79 - Easy wrapping of Python objects from C++ with smart, reference-counting PythonQtObjectPtr.
81 - Easy wrapping of Python objects from C++ with smart, reference-counting PythonQtObjectPtr.
80 - Convenient conversions to/from QVariant for PythonQtObjectPtr.
82 - Convenient conversions to/from QVariant for PythonQtObjectPtr.
81 - Wrapping of C++ objects (which are not derived from QObject) via PythonQtCppWrapperFactory
83 - 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)
84 - 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
85 - 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 (PythonQtImportFileInterface)
86 - 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
87 - 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
88 - Support for wrapping of user QVariant types which are registerd via QMetaType
87 - Support for Qt namespace (with all enumerators)
89 - Support for Qt namespace (with all enumerators)
88 - All PythonQt wrapped objects support the dir() statement, so that you can see easily which attributes a QObject, CPP object or QVariant has
90 - All PythonQt wrapped objects support the dir() statement, so that you can see easily which attributes a QObject, CPP object or QVariant has
89 - No preprocessing/wrapping tool needs to be started, PythonQt can script any QObject without prior knowledge about it (except for the MetaObject information from the \b moc)
91 - No preprocessing/wrapping tool needs to be started, PythonQt can script any QObject without prior knowledge about it (except for the MetaObject information from the \b moc)
90 - Multiple inheritance for C++ objects (e.g. a QWidget is derived from QObject and QPaintDevice, PythonQt will automatically cast a QWidget to a QPaintDevice when needed)
92 - Multiple inheritance for C++ objects (e.g. a QWidget is derived from QObject and QPaintDevice, PythonQt will automatically cast a QWidget to a QPaintDevice when needed)
91 - Polymorphic downcasting (if e.g. PythonQt sees a QEvent, it can downcast it depending on the type(), so the Python e.g. sees a QPaintEvent instead of a plain QEvent)
93 - Polymorphic downcasting (if e.g. PythonQt sees a QEvent, it can downcast it depending on the type(), so the Python e.g. sees a QPaintEvent instead of a plain QEvent)
92 - Deriving C++ objects from Python and overwriting virtual method with a Python implementation (requires usage of wrapper generator or manual work!)
94 - Deriving C++ objects from Python and overwriting virtual method with a Python implementation (requires usage of wrapper generator or manual work!)
93 - Extensible handler for Python/C++ conversion of complex types, e.g. mapping of QVector<SomeObject> to/from a Python array
95 - Extensible handler for Python/C++ conversion of complex types, e.g. mapping of QVector<SomeObject> to/from a Python array
94 - Setting of dynamic QObject properties via setProperty(), dynamic properties can be accessed for reading and writing like normal Python attributes (but creating a new property needs to be done with setProperty(), to distinguish from normal Python attributes)
96 - Setting of dynamic QObject properties via setProperty(), dynamic properties can be accessed for reading and writing like normal Python attributes (but creating a new property needs to be done with setProperty(), to distinguish from normal Python attributes)
95
97
96 \section FeaturesQtAll Features with wrapper generator
98 \section FeaturesQtAll Features with wrapper generator
97
99
98 Thanks to the new wrapper generator, PythonQt now offers the additional PythonQt_QtAll library which wraps the complete Qt API, including all C++ classes and all non-slots on QObject derived classes.
100 Thanks to the new wrapper generator, PythonQt now offers the additional PythonQt_QtAll library which wraps the complete Qt API, including all C++ classes and all non-slots on QObject derived classes.
99 This offers the following features:
101 This offers the following features:
100
102
101 - Complete Qt API wrapped and accessible
103 - Complete Qt API wrapped and accessible
102 - The following modules are available as submodules of the PythonQt module:
104 - The following modules are available as submodules of the PythonQt module:
103 - QtCore
105 - QtCore
104 - QtGui
106 - QtGui
105 - QtNetwork
107 - QtNetwork
106 - QtOpenGL
108 - QtOpenGL
107 - QtSql
109 - QtSql
108 - QtSvg
110 - QtSvg
109 - QtUiTools
111 - QtUiTools
110 - QtWebKit
112 - QtWebKit
111 - QtXml
113 - QtXml
112 - (QtXmlPatterns, QtScript, QtHelp, phonon, assistant, designer are currently not supported, this would require some additional effort on the code generator)
114 - (QtXmlPatterns, QtScript, QtHelp, phonon, assistant, designer are currently not supported, this would require some additional effort on the code generator)
113 - For convenience, all classes are also available in the PythonQt.Qt module, for people who do not care in which module a class is located
115 - For convenience, all classes are also available in the PythonQt.Qt module, for people who do not care in which module a class is located
114 - Any Qt class that has virtual methods can be easily derived from Python and the virtual methods can be reimplemented in Python (this feature is considered experimental!)
116 - Any Qt class that has virtual methods can be easily derived from Python and the virtual methods can be reimplemented in Python (this feature is considered experimental!)
115 - Polymorphic downcasting on QEvent, QGraphicsItem, QStyleOption, ...
117 - Polymorphic downcasting on QEvent, QGraphicsItem, QStyleOption, ...
116 - Multiple inheritance support (e.g., QGraphicsTextItem is a QObject AND a QGraphicsItem, PythonQt will handle this well)
118 - Multiple inheritance support (e.g., QGraphicsTextItem is a QObject AND a QGraphicsItem, PythonQt will handle this well)
117
119
120 \section Comparison Comparison with PyQt/PySide
121
122 - PythonQt is not as pythonic as PyQt in many details (e.g. buffer protocol, pickling, translation support, ...) and it is mainly thought for embedding and intercommunication between Qt/Cpp and Python
123 - PythonQt allows to communicate in both directions, e.g., calling a Python object from C++ AND calling a C++ method from Python, while PyQt only handles the Python->C++ direction
124 - PythonQt offers properties as Python attributes, while PyQt offers them as setter/getter methods (e.g. QWidget.width is a property in PythonQt and a method in PyQt)
125 - PythonQt currently does not support instanceof checks for Qt classes, except for the exact match and derived Python classes
126 - QObject.emit to emit Qt signals from Python is not yet implemented but PythonQt allows to just emit a signal by calling it like a normal slot
127 - PythonQt does not (yet) offer to add new signals to Python/C++ objects and it does not yet support the newstyle PyQt signals (so you need to connect via C++ string signatures)
128 - Ownership of objects is a bit different in PythonQt, currently Python classes derived from a C++ class need to be manually referenced in Python to not get deleted too early (this will be fixed in a future version)
129 - QStrings are always converted to unicode Python objects, QByteArray always stays a QByteArray and can be converted using str()
130 - There are many details in the generated wrappers that could need some polishing, e.g., methods that use pointer arguments for additional return values could return a results tuple.
131 - Not all types of QList/QVector/QHash templates are supported, some Qt methods use those as arguments/return values (but you can add your own handlers to handle them if you need them).
132 - Probably there are lots of details that differ, I do not know PyQt that well to list them all.
133 - In the long run, PythonQt will consider using/extending PySide with the features of PythonQt to get rid of its own generator and typesystem files, alternatively the KDE Smoke generator might be used in the future (this has not yet been decided, the current PythonQt generator works well and there is no hurry to switch).
134
118 \page Download Download
135 \page Download Download
119
136
120 PythonQt is hosted on SourceForge at http://sourceforge.net/projects/pythonqt.
137 PythonQt is hosted on <a href="http://sourceforge.net/projects/pythonqt/" target="_blank">SourceForge</a>.
121
138
122 You can download the source code as a tarball at http://sourceforge.net/projects/pythonqt/files/.
139 You can download the source code as a tarball at http://sourceforge.net/projects/pythonqt/files/.
123 Alternatively you can get the latest version from the svn repository.
140 Alternatively you can get the latest version from the svn repository.
124
141
125 You can also browse the source code online via ViewVC: http://pythonqt.svn.sourceforge.net/viewvc/pythonqt/trunk/
142 You can also browse the source code online via ViewVC: http://pythonqt.svn.sourceforge.net/viewvc/pythonqt/trunk/
126
143
127 \note We do not offer prebuilt binaries, since there are so many possible combinations of
144 \note We do not offer prebuilt binaries, since there are so many possible combinations of
128 platforms (Windows/Linux/MacOs), architectures (32/64 bit) and Python versions.
145 platforms (Windows/Linux/MacOs), architectures (32/64 bit) and Python versions.
129
146
130 \page License License
147 \page License License
131
148
132 PythonQt is distributed under the LGPL license, so it pairs well with the LGPL of the Qt 4.5 release and allows
149 PythonQt is distributed under the LGPL license, so it pairs well with the LGPL of the Qt 4.5 release and allows
133 to be used in commercial applications when following the LGPL 2.1 obligations.
150 to be used in commercial applications when following the LGPL 2.1 obligations.
134
151
135 The build system of PythonQt makes use of a modified version of the LGPL'ed QtScript generator,
152 The build system of PythonQt makes use of a modified version of the LGPL'ed QtScript generator,
136 located in the "generator" directory.
153 located in the "generator" directory.
137
154
138 See http://qt.gitorious.org/qt-labs/qtscriptgenerator for details on the original project.
155 See http://qt.gitorious.org/qt-labs/qtscriptgenerator for details on the original project.
139 Thanks a lot to the QtJambi guys and the QtScript Generator project for the C++ parser and
156 Thanks a lot to the QtJambi guys and the QtScript Generator project for the C++ parser and
140 Qt typesystem files!
157 Qt typesystem files!
141
158
142 The PythonQt wrappers generated by the generator located in the "generated_cpp" directory are free to be used without any licensing restrictions.
159 The PythonQt wrappers generated by the generator located in the "generated_cpp" directory are free to be used without any licensing restrictions.
143
160
144 The generated wrappers are pre-generated and checked-in for Qt 4.6.1, so you only need to build and run the
161 The generated wrappers are pre-generated and checked-in for Qt 4.6.1, so you only need to build and run the
145 generator when you want to build additional wrappers or you want to upgrade/downgrade to another Qt version.
162 generator when you want to build additional wrappers or you want to upgrade/downgrade to another Qt version.
146 You may use the generator to generate C++ bindings for your own C++ classes (e.g., to make them inheritable in Python),
163 You may use the generator to generate C++ bindings for your own C++ classes (e.g., to make them inheritable in Python),
147 but this is currently not documented and involves creating your own typesystem files (although the Qt Jambi examples might help you).
164 but this is currently not documented and involves creating your own typesystem files (although the Qt Jambi examples might help you).
148
165
149 \section Comparison Comparison with PyQt/PySide
150
151 - PythonQt is not as pythonic as PyQt in many details (e.g. buffer protocol, pickling, translation support, ...) and it is mainly thought for embedding and intercommunication between Qt/Cpp and Python
152 - PythonQt allows to communicate in both directions, e.g., calling a Python object from C++ AND calling a C++ method from Python, while PyQt only handles the Python->C++ direction
153 - PythonQt offers properties as Python attributes, while PyQt offers them as setter/getter methods (e.g. QWidget.width is a property in PythonQt and a method in PyQt)
154 - PythonQt currently does not support instanceof checks for Qt classes, except for the exact match and derived Python classes
155 - QObject.emit to emit Qt signals from Python is not yet implemented but PythonQt allows to just emit a signal by calling it like a normal slot
156 - PythonQt does not (yet) offer to add new signals to Python/C++ objects and it does not yet support the newstyle PyQt signals (so you need to connect via C++ string signatures)
157 - Ownership of objects is a bit different in PythonQt, currently Python classes derived from a C++ class need to be manually referenced in Python to not get deleted too early (this will be fixed in a future version)
158 - QStrings are always converted to unicode Python objects, QByteArray always stays a QByteArray and can be converted using str()
159 - There are many details in the generated wrappers that could need some polishing, e.g., methods that use pointer arguments for additional return values could return a results tuple.
160 - Not all types of QList/QVector/QHash templates are supported, some Qt methods use those as arguments/return values (but you can add your own handlers to handle them if you need them).
161 - Probably there are lots of details that differ, I do not know PyQt that well to list them all.
162 - In the long run, PythonQt will consider using/extending PySide with the features of PythonQt to get rid of its own generator and typesystem files, alternatively the KDE Smoke generator might be used in the future (this has not yet been decided, the current PythonQt generator works well and there is no hurry to switch).
163
166
164 \page Developer Developer
167 \page Developer Developer
165
168
166 \section Interface Interface
169 \section Interface Interface
167
170
168 The main interface to PythonQt is the PythonQt singleton.
171 The main interface to PythonQt is the PythonQt singleton.
169 PythonQt needs to be initialized via PythonQt::init() once.
172 PythonQt needs to be initialized via PythonQt::init() once.
170 Afterwards you communicate with the singleton via PythonQt::self().
173 Afterwards you communicate with the singleton via PythonQt::self().
171 PythonQt offers a complete Qt binding, which
174 PythonQt offers a complete Qt binding, which
172 needs to be enabled via PythonQt_QtAll::init().
175 needs to be enabled via PythonQt_QtAll::init().
173
176
174
177
175 \section Datatype Datatype Mapping
178 \section Datatype Datatype Mapping
176
179
177 The following table shows the mapping between Python and Qt objects:
180 The following table shows the mapping between Python and Qt objects:
178 <table>
181 <table>
179 <tr><th>Qt/C++</th><th>Python</th></tr>
182 <tr><th>Qt/C++</th><th>Python</th></tr>
180 <tr><td>bool</td><td>bool</td></tr>
183 <tr><td>bool</td><td>bool</td></tr>
181 <tr><td>double</td><td>float</td></tr>
184 <tr><td>double</td><td>float</td></tr>
182 <tr><td>float</td><td>float</td></tr>
185 <tr><td>float</td><td>float</td></tr>
183 <tr><td>char/uchar,int/uint,short,ushort,QChar</td><td>integer</td></tr>
186 <tr><td>char/uchar,int/uint,short,ushort,QChar</td><td>integer</td></tr>
184 <tr><td>long</td><td>integer</td></tr>
187 <tr><td>long</td><td>integer</td></tr>
185 <tr><td>ulong,longlong,ulonglong</td><td>long</td></tr>
188 <tr><td>ulong,longlong,ulonglong</td><td>long</td></tr>
186 <tr><td>QString</td><td>unicode string</td></tr>
189 <tr><td>QString</td><td>unicode string</td></tr>
187 <tr><td>QByteArray</td><td>QByteArray wrapper</td></tr>
190 <tr><td>QByteArray</td><td>QByteArray wrapper</td></tr>
188 <tr><td>char*</td><td>str</td></tr>
191 <tr><td>char*</td><td>str</td></tr>
189 <tr><td>QStringList</td><td>tuple of unicode strings</td></tr>
192 <tr><td>QStringList</td><td>tuple of unicode strings</td></tr>
190 <tr><td>QVariantList</td><td>tuple of objects</td></tr>
193 <tr><td>QVariantList</td><td>tuple of objects</td></tr>
191 <tr><td>QVariantMap</td><td>dict of objects</td></tr>
194 <tr><td>QVariantMap</td><td>dict of objects</td></tr>
192 <tr><td>QVariant</td><td>depends on type, see below</td></tr>
195 <tr><td>QVariant</td><td>depends on type, see below</td></tr>
193 <tr><td>QSize, QRect and all other standard Qt QVariants</td><td>variant wrapper that supports complete API of the respective Qt classes</td></tr>
196 <tr><td>QSize, QRect and all other standard Qt QVariants</td><td>variant wrapper that supports complete API of the respective Qt classes</td></tr>
194 <tr><td>OwnRegisteredMetaType</td><td>C++ wrapper, optionally with additional information/wrapping provided by registerCPPClass()</td></tr>
197 <tr><td>OwnRegisteredMetaType</td><td>C++ wrapper, optionally with additional information/wrapping provided by registerCPPClass()</td></tr>
195 <tr><td>QList<AnyObject*></td><td>converts to a list of CPP wrappers</td></tr>
198 <tr><td>QList<AnyObject*></td><td>converts to a list of CPP wrappers</td></tr>
196 <tr><td>QVector<AnyObject*></td><td>converts to a list of CPP wrappers</td></tr>
199 <tr><td>QVector<AnyObject*></td><td>converts to a list of CPP wrappers</td></tr>
197 <tr><td>EnumType</td><td>Enum wrapper derived from python integer</td></tr>
200 <tr><td>EnumType</td><td>Enum wrapper derived from python integer</td></tr>
198 <tr><td>QObject (and derived classes)</td><td>QObject wrapper</td></tr>
201 <tr><td>QObject (and derived classes)</td><td>QObject wrapper</td></tr>
199 <tr><td>C++ object</td><td>CPP wrapper, either wrapped via PythonQtCppWrapperFactory or just decorated with decorators</td></tr>
202 <tr><td>C++ object</td><td>CPP wrapper, either wrapped via PythonQtCppWrapperFactory or just decorated with decorators</td></tr>
200 <tr><td>PyObject</td><td>PyObject</td></tr>
203 <tr><td>PyObject</td><td>PyObject</td></tr>
201 </table>
204 </table>
202
205
203 PyObject is passed as direct pointer, which allows to pass/return any Python object directly to/from
206 PyObject is passed as direct pointer, which allows to pass/return any Python object directly to/from
204 a Qt slot that uses PyObject* as its argument/return value.
207 a Qt slot that uses PyObject* as its argument/return value.
205 QVariants are mapped recursively as given above, e.g. a dictionary can
208 QVariants are mapped recursively as given above, e.g. a dictionary can
206 contain lists of dictionaries of doubles.
209 contain lists of dictionaries of doubles.
207 All Qt QVariant types are implemented, PythonQt supports the complete Qt API for these object.
210 All Qt QVariant types are implemented, PythonQt supports the complete Qt API for these object.
208
211
209 \section QObject QObject Wrapping
212 \section QObject QObject Wrapping
210
213
211 All classes derived from QObject are automatically wrapped with a python wrapper class
214 All classes derived from QObject are automatically wrapped with a python wrapper class
212 when they become visible to the Python interpreter. This can happen via
215 when they become visible to the Python interpreter. This can happen via
213 - the PythonQt::addObject() method
216 - the PythonQt::addObject() method
214 - when a Qt \b slot returns a QObject derived object to python
217 - when a Qt \b slot returns a QObject derived object to python
215 - when a Qt \b signal contains a QObject and is connected to a python function
218 - when a Qt \b signal contains a QObject and is connected to a python function
216
219
217 It is important that you call PythonQt::registerClass() for any QObject derived class
220 It is important that you call PythonQt::registerClass() for any QObject derived class
218 that may become visible to Python, except when you add it via PythonQt::addObject().
221 that may become visible to Python, except when you add it via PythonQt::addObject().
219 This will register the complete parent hierachy of the registered class, so that
222 This will register the complete parent hierachy of the registered class, so that
220 when you register e.g. a QPushButton, QWidget will be registered as well (and all intermediate
223 when you register e.g. a QPushButton, QWidget will be registered as well (and all intermediate
221 parents).
224 parents).
222
225
223 From Python, you can talk to the returned QObjects in a natural way by calling
226 From Python, you can talk to the returned QObjects in a natural way by calling
224 their slots and receiving the return values. You can also read/write all
227 their slots and receiving the return values. You can also read/write all
225 properties of the objects as if they where normal python properties.
228 properties of the objects as if they where normal python properties.
226
229
227 In addition to this, the wrapped objects support
230 In addition to this, the wrapped objects support
228 - className() - returns a string that reprents the classname of the QObject
231 - className() - returns a string that reprents the classname of the QObject
229 - help() - shows all properties, slots, enums, decorator slots and constructors of the object, in a printable form
232 - help() - shows all properties, slots, enums, decorator slots and constructors of the object, in a printable form
230 - delete() - deletes the object (use with care, especially if you passed the ownership to C++)
233 - delete() - deletes the object (use with care, especially if you passed the ownership to C++)
231 - connect(signal, function) - connect the signal of the given object to a python function
234 - connect(signal, function) - connect the signal of the given object to a python function
232 - connect(signal, qobject, slot) - connect the signal of the given object to a slot of another QObject
235 - connect(signal, qobject, slot) - connect the signal of the given object to a slot of another QObject
233 - disconnect(signal, function) - disconnect the signal of the given object from a python function
236 - disconnect(signal, function) - disconnect the signal of the given object from a python function
234 - disconnect(signal, qobject, slot) - disconnect the signal of the given object from a slot of another QObject
237 - disconnect(signal, qobject, slot) - disconnect the signal of the given object from a slot of another QObject
235 - children() - returns the children of the object
238 - children() - returns the children of the object
236 - setParent(QObject) - set the parent
239 - setParent(QObject) - set the parent
237 - QObject* parent() - get the parent
240 - QObject* parent() - get the parent
238
241
239 The below example shows how to connect signals in Python:
242 The below example shows how to connect signals in Python:
240
243
241 \code
244 \code
242 # define a signal handler function
245 # define a signal handler function
243 def someFunction(flag):
246 def someFunction(flag):
244 print flag
247 print flag
245
248
246 # button1 is a QPushButton that has been added to Python via addObject()
249 # button1 is a QPushButton that has been added to Python via addObject()
247 # connect the clicked signal to a python function:
250 # connect the clicked signal to a python function:
248 button1.connect("clicked(bool)", someFunction)
251 button1.connect("clicked(bool)", someFunction)
249
252
250 \endcode
253 \endcode
251
254
252 \section CPP CPP Wrapping
255 \section CPP CPP Wrapping
253
256
254 You can create dedicated wrapper QObjects for any C++ class. This is done by deriving from PythonQtCppWrapperFactory
257 You can create dedicated wrapper QObjects for any C++ class. This is done by deriving from PythonQtCppWrapperFactory
255 and adding your factory via addWrapperFactory().
258 and adding your factory via addWrapperFactory().
256 Whenever PythonQt encounters a CPP pointer (e.g. on a slot or signal)
259 Whenever PythonQt encounters a CPP pointer (e.g. on a slot or signal)
257 and it does not known it as a QObject derived class, it will create a generic CPP wrapper. So even unknown C++ objects
260 and it does not known it as a QObject derived class, it will create a generic CPP wrapper. So even unknown C++ objects
258 can be passed through Python. If the wrapper factory supports the CPP class, a QObject wrapper will be created for each
261 can be passed through Python. If the wrapper factory supports the CPP class, a QObject wrapper will be created for each
259 instance that enters Python. An alternative to a complete wrapper via the wrapper factory are decorators, see \ref Decorators
262 instance that enters Python. An alternative to a complete wrapper via the wrapper factory are decorators, see \ref Decorators
260
263
261 \section MetaObject Meta Object/Class access
264 \section MetaObject Meta Object/Class access
262
265
263 For each known C++ class, PythonQt provides a Python class. These classes are visible
266 For each known C++ class, PythonQt provides a Python class. These classes are visible
264 inside of the "PythonQt" python module or in subpackages if a package is given when the class is registered.
267 inside of the "PythonQt" python module or in subpackages if a package is given when the class is registered.
265
268
266 A Meta class supports:
269 A Meta class supports:
267
270
268 - access to all declared enum values
271 - access to all declared enum values
269 - constructors
272 - constructors
270 - static methods
273 - static methods
271 - unbound non-static methods
274 - unbound non-static methods
272 - help() and className()
275 - help() and className()
273
276
274 From within Python, you can import the module "PythonQt" to access these classes and the Qt namespace.
277 From within Python, you can import the module "PythonQt" to access these classes and the Qt namespace.
275
278
276 \code
279 \code
277 from PythonQt import QtCore
280 from PythonQt import QtCore
278
281
279 # namespace access:
282 # namespace access:
280 print QtCore.Qt.AlignLeft
283 print QtCore.Qt.AlignLeft
281
284
282 # constructors
285 # constructors
283 a = QtCore.QSize(12,13)
286 a = QtCore.QSize(12,13)
284 b = QtCore.QFont()
287 b = QtCore.QFont()
285
288
286 # static method
289 # static method
287 QtCore.QDate.currentDate()
290 QtCore.QDate.currentDate()
288
291
289 # enum value
292 # enum value
290 QtCore.QFont.UltraCondensed
293 QtCore.QFont.UltraCondensed
291
294
292 \endcode
295 \endcode
293
296
294 \section Decorators Decorator slots
297 \section Decorators Decorator slots
295
298
296 PythonQt introduces a new generic approach to extend any wrapped QObject or CPP object with
299 PythonQt introduces a new generic approach to extend any wrapped QObject or CPP object with
297
300
298 - constructors
301 - constructors
299 - destructors (for CPP objects)
302 - destructors (for CPP objects)
300 - additional slots
303 - additional slots
301 - static slots (callable on both the Meta object and the instances)
304 - static slots (callable on both the Meta object and the instances)
302
305
303 The idea behind decorators is that we wanted to make it as easy as possible to extend
306 The idea behind decorators is that we wanted to make it as easy as possible to extend
304 wrapped objects. Since we already have an implementation for invoking any Qt Slot from
307 wrapped objects. Since we already have an implementation for invoking any Qt Slot from
305 Python, it looked promising to use this approach for the extension of wrapped objects as well.
308 Python, it looked promising to use this approach for the extension of wrapped objects as well.
306 This avoids that the PythonQt user needs to care about how Python arguments are mapped from/to
309 This avoids that the PythonQt user needs to care about how Python arguments are mapped from/to
307 Qt when he wants to create static methods, constructors and additional member functions.
310 Qt when he wants to create static methods, constructors and additional member functions.
308
311
309 The basic idea about decorators is to create a QObject derived class that implements slots
312 The basic idea about decorators is to create a QObject derived class that implements slots
310 which take one of the above roles (e.g. constructor, destructor etc.) via a naming convention.
313 which take one of the above roles (e.g. constructor, destructor etc.) via a naming convention.
311 These slots are then assigned to other classes via the naming convention.
314 These slots are then assigned to other classes via the naming convention.
312
315
313 - SomeClassName* new_SomeClassName(...) - defines a constructor for "SomeClassName" that returns a new object of type SomeClassName (where SomeClassName can be any CPP class, not just QObject classes)
316 - SomeClassName* new_SomeClassName(...) - defines a constructor for "SomeClassName" that returns a new object of type SomeClassName (where SomeClassName can be any CPP class, not just QObject classes)
314 - void delete_SomeClassName(SomeClassName* o) - defines a destructor, which should delete the passed in object o
317 - void delete_SomeClassName(SomeClassName* o) - defines a destructor, which should delete the passed in object o
315 - anything static_SomeClassName_someMethodName(...) - defines a static method that is callable on instances and the meta class
318 - anything static_SomeClassName_someMethodName(...) - defines a static method that is callable on instances and the meta class
316 - anything someMethodName(SomeClassName* o, ...) - defines a slot that will be available on SomeClassName instances (and derived instances). When such a slot is called the first argument is the pointer to the instance and the rest of the arguments can be used to make a call on the instance.
319 - anything someMethodName(SomeClassName* o, ...) - defines a slot that will be available on SomeClassName instances (and derived instances). When such a slot is called the first argument is the pointer to the instance and the rest of the arguments can be used to make a call on the instance.
317
320
318 The below example shows all kinds of decorators in action:
321 The below example shows all kinds of decorators in action:
319
322
320 \code
323 \code
321
324
322 // an example CPP object
325 // an example CPP object
323 class YourCPPObject {
326 class YourCPPObject {
324 public:
327 public:
325 YourCPPObject(int arg1, float arg2) { a = arg1; b = arg2; }
328 YourCPPObject(int arg1, float arg2) { a = arg1; b = arg2; }
326
329
327 float doSomething(int arg1) { return arg1*a*b; };
330 float doSomething(int arg1) { return arg1*a*b; };
328
331
329 private:
332 private:
330
333
331 int a;
334 int a;
332 float b;
335 float b;
333 };
336 };
334
337
335 // an example decorator
338 // an example decorator
336 class ExampleDecorator : public QObject
339 class ExampleDecorator : public QObject
337 {
340 {
338 Q_OBJECT
341 Q_OBJECT
339
342
340 public slots:
343 public slots:
341 // add a constructor to QSize that takes a QPoint
344 // add a constructor to QSize that takes a QPoint
342 QSize* new_QSize(const QPoint& p) { return new QSize(p.x(), p.y()); }
345 QSize* new_QSize(const QPoint& p) { return new QSize(p.x(), p.y()); }
343
346
344 // add a constructor for QPushButton that takes a text and a parent widget
347 // add a constructor for QPushButton that takes a text and a parent widget
345 QPushButton* new_QPushButton(const QString& text, QWidget* parent=NULL) { return new QPushButton(text, parent); }
348 QPushButton* new_QPushButton(const QString& text, QWidget* parent=NULL) { return new QPushButton(text, parent); }
346
349
347 // add a constructor for a CPP object
350 // add a constructor for a CPP object
348 YourCPPObject* new_YourCPPObject(int arg1, float arg2) { return new YourCPPObject(arg1, arg2); }
351 YourCPPObject* new_YourCPPObject(int arg1, float arg2) { return new YourCPPObject(arg1, arg2); }
349
352
350 // add a destructor for a CPP object
353 // add a destructor for a CPP object
351 void delete_YourCPPObject(YourCPPObject* obj) { delete obj; }
354 void delete_YourCPPObject(YourCPPObject* obj) { delete obj; }
352
355
353 // add a static method to QWidget
356 // add a static method to QWidget
354 QWidget* static_QWidget_mouseGrabber() { return QWidget::mouseGrabber(); }
357 QWidget* static_QWidget_mouseGrabber() { return QWidget::mouseGrabber(); }
355
358
356 // add an additional slot to QWidget (make move() callable, which is not declared as a slot in QWidget)
359 // add an additional slot to QWidget (make move() callable, which is not declared as a slot in QWidget)
357 void move(QWidget* w, const QPoint& p) { w->move(p); }
360 void move(QWidget* w, const QPoint& p) { w->move(p); }
358
361
359 // add an additional slot to QWidget, overloading the above move method
362 // add an additional slot to QWidget, overloading the above move method
360 void move(QWidget* w, int x, int y) { w->move(x,y); }
363 void move(QWidget* w, int x, int y) { w->move(x,y); }
361
364
362 // add a method to your own CPP object
365 // add a method to your own CPP object
363 int doSomething(YourCPPObject* obj, int arg1) { return obj->doSomething(arg1); }
366 int doSomething(YourCPPObject* obj, int arg1) { return obj->doSomething(arg1); }
364 };
367 };
365
368
366 ...
369 ...
367
370
368 PythonQt::self()->addDecorators(new ExampleDecorator());
371 PythonQt::self()->addDecorators(new ExampleDecorator());
369 PythonQt::self()->registerCPPClass("YourCPPObject");
372 PythonQt::self()->registerCPPClass("YourCPPObject");
370
373
371 \endcode
374 \endcode
372
375
373 After you have registered an instance of the above ExampleDecorator, you can do the following from Python
376 After you have registered an instance of the above ExampleDecorator, you can do the following from Python
374 (all these calls are mapped to the above decorator slots):
377 (all these calls are mapped to the above decorator slots):
375
378
376 \code
379 \code
377 from PythonQt import QtCore, QtGui, YourCPPObject
380 from PythonQt import QtCore, QtGui, YourCPPObject
378
381
379 # call our new constructor of QSize
382 # call our new constructor of QSize
380 size = QtCore.QSize(QPoint(1,2));
383 size = QtCore.QSize(QPoint(1,2));
381
384
382 # call our new QPushButton constructor
385 # call our new QPushButton constructor
383 button = QtGui.QPushButton("sometext");
386 button = QtGui.QPushButton("sometext");
384
387
385 # call the move slot (overload1)
388 # call the move slot (overload1)
386 button.move(QPoint(0,0))
389 button.move(QPoint(0,0))
387
390
388 # call the move slot (overload2)
391 # call the move slot (overload2)
389 button.move(0,0)
392 button.move(0,0)
390
393
391 # call the static method
394 # call the static method
392 grabber = QtGui.QWidget.mouseWrapper();
395 grabber = QtGui.QWidget.mouseWrapper();
393
396
394 # create a CPP object via constructor
397 # create a CPP object via constructor
395 yourCpp = YourCPPObject(1,11.5)
398 yourCpp = YourCPPObject(1,11.5)
396
399
397 # call the wrapped method on CPP object
400 # call the wrapped method on CPP object
398 print yourCpp.doSomething(1);
401 print yourCpp.doSomething(1);
399
402
400 # destructor will be called:
403 # destructor will be called:
401 yourCpp = None
404 yourCpp = None
402
405
403 \endcode
406 \endcode
404
407
405 \page Building Building
408 \page Building Building
406
409
407 PythonQt requires at least Qt 4.6.1 (for earlier Qt versions, you will need to run the pythonqt_gerenator, Qt 4.3 is the absolute minimum) and Python 2.5.x or 2.6.x on Windows, Linux and MacOS X. It has not yet been tested with Python 3.x, but it should only require minor changes.
410 PythonQt requires at least Qt 4.6.1 (for earlier Qt versions, you will need to run the pythonqt_gerenator, Qt 4.3 is the absolute minimum) and Python 2.5.x or 2.6.x on Windows, Linux and MacOS X. It has not yet been tested with Python 3.x, but it should only require minor changes.
408 To compile PythonQt, you will need a python developer installation which includes Python's header files and
411 To compile PythonQt, you will need a python developer installation which includes Python's header files and
409 the python2x.[lib | dll | so | dynlib].
412 the python2x.[lib | dll | so | dynlib].
410 The build scripts a currently set to use Python 2.6.
413 The build scripts a currently set to use Python 2.6.
411 You may need to tweak the \b build/python.prf file to set the correct Python includes and libs on your system.
414 You may need to tweak the \b build/python.prf file to set the correct Python includes and libs on your system.
412
415
413 \subsection Windows
416 \subsection Windows
414
417
415 On Windows, the (non-source) Python Windows installer can be used.
418 On Windows, the (non-source) Python Windows installer can be used.
416 Make sure that you use the same compiler, the current Python distribution is built
419 Make sure that you use the same compiler, the current Python distribution is built
417 with Visual Studio 2003. If you want to use another compiler, you will need to build
420 with Visual Studio 2003. If you want to use another compiler, you will need to build
418 Python yourself, using your compiler.
421 Python yourself, using your compiler.
419
422
420 To build PythonQt, you need to set the environment variable \b PYTHON_PATH to point to the root
423 To build PythonQt, you need to set the environment variable \b PYTHON_PATH to point to the root
421 dir of the python installation and \b PYTHON_LIB to point to
424 dir of the python installation and \b PYTHON_LIB to point to
422 the directory where the python lib file is located.
425 the directory where the python lib file is located.
423
426
424 When using the prebuild Python installer, this will be:
427 When using the prebuild Python installer, this will be:
425
428
426 \code
429 \code
427 > set PYTHON_PATH = c:\Python26
430 > set PYTHON_PATH = c:\Python26
428 > set PYTHON_LIB = c:\Python26\libs
431 > set PYTHON_LIB = c:\Python26\libs
429 \endcode
432 \endcode
430
433
431 When using the python sources, this will be something like:
434 When using the python sources, this will be something like:
432
435
433 \code
436 \code
434 > set PYTHON_PATH = c:\yourDir\Python-2.6.1\
437 > set PYTHON_PATH = c:\yourDir\Python-2.6.1\
435 > set PYTHON_LIB = c:\yourDir\Python-2.6.1\PCbuild8\Win32
438 > set PYTHON_LIB = c:\yourDir\Python-2.6.1\PCbuild8\Win32
436 \endcode
439 \endcode
437
440
438 To build all, do the following (after setting the above variables):
441 To build all, do the following (after setting the above variables):
439
442
440 \code
443 \code
441 > cd PythonQtRoot
444 > cd PythonQtRoot
442 > vcvars32
445 > vcvars32
443 > qmake
446 > qmake
444 > nmake
447 > nmake
445 \endcode
448 \endcode
446
449
447 This should build everything. If Python can not be linked or include files can not be found,
450 This should build everything. If Python can not be linked or include files can not be found,
448 you probably need to tweak \b build/python.prf
451 you probably need to tweak \b build/python.prf
449
452
450 The tests and examples are located in PythonQt/lib.
453 The tests and examples are located in PythonQt/lib.
451
454
452 \subsection Linux
455 \subsection Linux
453
456
454 On Linux, you need to install a Python-dev package.
457 On Linux, you need to install a Python-dev package.
455 If Python can not be linked or include files can not be found,
458 If Python can not be linked or include files can not be found,
456 you probably need to tweak \b build/python.prf
459 you probably need to tweak \b build/python.prf
457
460
458 To build PythonQt, just do a:
461 To build PythonQt, just do a:
459
462
460 \code
463 \code
461 > cd PythonQtRoot
464 > cd PythonQtRoot
462 > qmake
465 > qmake
463 > make all
466 > make all
464 \endcode
467 \endcode
465
468
466 The tests and examples are located in PythonQt/lib.
469 The tests and examples are located in PythonQt/lib.
467 You should add PythonQt/lib to your LD_LIBRARY_PATH so that the runtime
470 You should add PythonQt/lib to your LD_LIBRARY_PATH so that the runtime
468 linker can find the *.so files.
471 linker can find the *.so files.
469
472
470 \subsection MacOsX
473 \subsection MacOsX
471
474
472 On Mac, Python is installed as a Framework, so you should not need to install it.
475 On Mac, Python is installed as a Framework, so you should not need to install it.
473 To build PythonQt, just do a:
476 To build PythonQt, just do a:
474
477
475 \code
478 \code
476 > cd PythonQtRoot
479 > cd PythonQtRoot
477 > qmake
480 > qmake
478 > make all
481 > make all
479 \endcode
482 \endcode
480
483
481 \section Tests
484 \section Tests
482
485
483 There is a unit test that tests most features of PythonQt, see the \b tests subdirectory for details.
486 There is a unit test that tests most features of PythonQt, see the \b tests subdirectory for details.
484
487
485 \page Examples Examples
488 \page Examples Examples
486
489
487 Examples are available in the \b examples directory. The PyScriptingConsole implements a simple
490 Examples are available in the \b examples directory. The PyScriptingConsole implements a simple
488 interactive scripting console that shows how to script a simple application. The PyLauncher application can be used to run arbitrary PythonQt scripts given on the commandline.
491 interactive scripting console that shows how to script a simple application. The PyLauncher application can be used to run arbitrary PythonQt scripts given on the commandline.
489
492
490 The following shows a simple example on how to integrate PythonQt into your Qt application:
493 The following shows a simple example on how to integrate PythonQt into your Qt application:
491
494
492 \code
495 \code
493 #include "PythonQt.h"
496 #include "PythonQt.h"
494 #include <QApplication>
497 #include <QApplication>
495 ...
498 ...
496
499
497 int main( int argc, char **argv )
500 int main( int argc, char **argv )
498 {
501 {
499
502
500 QApplication qapp(argc, argv);
503 QApplication qapp(argc, argv);
501
504
502 // init PythonQt and Python itself
505 // init PythonQt and Python itself
503 PythonQt::init();
506 PythonQt::init();
504
507
505 // get a smart pointer to the __main__ module of the Python interpreter
508 // get a smart pointer to the __main__ module of the Python interpreter
506 PythonQtObjectPtr context = PythonQt::self()->getMainModule();
509 PythonQtObjectPtr context = PythonQt::self()->getMainModule();
507
510
508 // add a QObject as variable of name "example" to the namespace of the __main__ module
511 // add a QObject as variable of name "example" to the namespace of the __main__ module
509 PyExampleObject example;
512 PyExampleObject example;
510 context.addObject("example", &example);
513 context.addObject("example", &example);
511
514
512 // do something
515 // do something
513 context.evalScript("print example");
516 context.evalScript("print example");
514 context.evalScript("def multiply(a,b):\n return a*b;\n");
517 context.evalScript("def multiply(a,b):\n return a*b;\n");
515 QVariantList args;
518 QVariantList args;
516 args << 42 << 47;
519 args << 42 << 47;
517 QVariant result = context.call("multiply", args);
520 QVariant result = context.call("multiply", args);
518 ...
521 ...
519 \endcode
522 \endcode
520
523
521
524
522 */
525 */
General Comments 0
You need to be logged in to leave comments. Login now