##// END OF EJS Templates
updated docs and exported class info...
florianlink -
r139:ad60447f50bd
parent child
Show More
@@ -1,262 +1,262
1 #ifndef _PYTHONQTCLASSINFO_H
1 #ifndef _PYTHONQTCLASSINFO_H
2 #define _PYTHONQTCLASSINFO_H
2 #define _PYTHONQTCLASSINFO_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 #include <QMetaObject>
36 #include <QMetaObject>
37 #include <QMetaMethod>
37 #include <QMetaMethod>
38 #include <QHash>
38 #include <QHash>
39 #include <QByteArray>
39 #include <QByteArray>
40 #include <QList>
40 #include <QList>
41 #include "PythonQt.h"
41 #include "PythonQt.h"
42
42
43 class PythonQtSlotInfo;
43 class PythonQtSlotInfo;
44
44
45 struct PythonQtMemberInfo {
45 struct PythonQtMemberInfo {
46 enum Type {
46 enum Type {
47 Invalid, Slot, EnumValue, EnumWrapper, Property, NotFound
47 Invalid, Slot, EnumValue, EnumWrapper, Property, NotFound
48 };
48 };
49
49
50 PythonQtMemberInfo():_type(Invalid),_slot(NULL),_enumWrapper(NULL),_enumValue(0) { }
50 PythonQtMemberInfo():_type(Invalid),_slot(NULL),_enumWrapper(NULL),_enumValue(0) { }
51
51
52 PythonQtMemberInfo(PythonQtSlotInfo* info) {
52 PythonQtMemberInfo(PythonQtSlotInfo* info) {
53 _type = Slot;
53 _type = Slot;
54 _slot = info;
54 _slot = info;
55 _enumValue = NULL;
55 _enumValue = NULL;
56 }
56 }
57
57
58 PythonQtMemberInfo(const PythonQtObjectPtr& enumValue) {
58 PythonQtMemberInfo(const PythonQtObjectPtr& enumValue) {
59 _type = EnumValue;
59 _type = EnumValue;
60 _slot = NULL;
60 _slot = NULL;
61 _enumValue = enumValue;
61 _enumValue = enumValue;
62 _enumWrapper = NULL;
62 _enumWrapper = NULL;
63 }
63 }
64
64
65 PythonQtMemberInfo(const QMetaProperty& prop) {
65 PythonQtMemberInfo(const QMetaProperty& prop) {
66 _type = Property;
66 _type = Property;
67 _slot = NULL;
67 _slot = NULL;
68 _enumValue = NULL;
68 _enumValue = NULL;
69 _property = prop;
69 _property = prop;
70 _enumWrapper = NULL;
70 _enumWrapper = NULL;
71 }
71 }
72
72
73 Type _type;
73 Type _type;
74
74
75 // TODO: this could be a union...
75 // TODO: this could be a union...
76 PythonQtSlotInfo* _slot;
76 PythonQtSlotInfo* _slot;
77 PyObject* _enumWrapper;
77 PyObject* _enumWrapper;
78 PythonQtObjectPtr _enumValue;
78 PythonQtObjectPtr _enumValue;
79 QMetaProperty _property;
79 QMetaProperty _property;
80 };
80 };
81
81
82 //! a class that stores all required information about a Qt object (and an optional associated C++ class name)
82 //! a class that stores all required information about a Qt object (and an optional associated C++ class name)
83 /*! for fast lookup of slots when calling the object from Python
83 /*! for fast lookup of slots when calling the object from Python
84 */
84 */
85 class PythonQtClassInfo {
85 class PYTHONQT_EXPORT PythonQtClassInfo {
86
86
87 public:
87 public:
88 PythonQtClassInfo();
88 PythonQtClassInfo();
89 ~PythonQtClassInfo();
89 ~PythonQtClassInfo();
90
90
91 //! store information about parent classes
91 //! store information about parent classes
92 struct ParentClassInfo {
92 struct ParentClassInfo {
93 ParentClassInfo(PythonQtClassInfo* parent, int upcastingOffset=0):_parent(parent),_upcastingOffset(upcastingOffset)
93 ParentClassInfo(PythonQtClassInfo* parent, int upcastingOffset=0):_parent(parent),_upcastingOffset(upcastingOffset)
94 {};
94 {};
95
95
96 PythonQtClassInfo* _parent;
96 PythonQtClassInfo* _parent;
97 int _upcastingOffset;
97 int _upcastingOffset;
98 };
98 };
99
99
100
100
101 //! setup as a QObject, taking the meta object as meta information about the QObject
101 //! setup as a QObject, taking the meta object as meta information about the QObject
102 void setupQObject(const QMetaObject* meta);
102 void setupQObject(const QMetaObject* meta);
103
103
104 //! setup as a CPP (non-QObject), taking the classname
104 //! setup as a CPP (non-QObject), taking the classname
105 void setupCPPObject(const QByteArray& classname);
105 void setupCPPObject(const QByteArray& classname);
106
106
107 //! set the type capabilities
107 //! set the type capabilities
108 void setTypeSlots(int typeSlots) { _typeSlots = typeSlots; }
108 void setTypeSlots(int typeSlots) { _typeSlots = typeSlots; }
109 //! get the type capabilities
109 //! get the type capabilities
110 int typeSlots() const { return _typeSlots; }
110 int typeSlots() const { return _typeSlots; }
111
111
112 //! get the Python method definition for a given slot name (without return type and signature)
112 //! get the Python method definition for a given slot name (without return type and signature)
113 PythonQtMemberInfo member(const char* member);
113 PythonQtMemberInfo member(const char* member);
114
114
115 //! get access to the constructor slot (which may be overloaded if there are multiple constructors)
115 //! get access to the constructor slot (which may be overloaded if there are multiple constructors)
116 PythonQtSlotInfo* constructors();
116 PythonQtSlotInfo* constructors();
117
117
118 //! get access to the destructor slot
118 //! get access to the destructor slot
119 PythonQtSlotInfo* destructor();
119 PythonQtSlotInfo* destructor();
120
120
121 //! add a constructor, ownership is passed to classinfo
121 //! add a constructor, ownership is passed to classinfo
122 void addConstructor(PythonQtSlotInfo* info);
122 void addConstructor(PythonQtSlotInfo* info);
123
123
124 //! set a destructor, ownership is passed to classinfo
124 //! set a destructor, ownership is passed to classinfo
125 void setDestructor(PythonQtSlotInfo* info);
125 void setDestructor(PythonQtSlotInfo* info);
126
126
127 //! add a decorator slot, ownership is passed to classinfo
127 //! add a decorator slot, ownership is passed to classinfo
128 void addDecoratorSlot(PythonQtSlotInfo* info);
128 void addDecoratorSlot(PythonQtSlotInfo* info);
129
129
130 //! get the classname (either of the QObject or of the wrapped CPP object)
130 //! get the classname (either of the QObject or of the wrapped CPP object)
131 const char* className();
131 const char* className();
132
132
133 //! returns if the QObject
133 //! returns if the QObject
134 bool isQObject() { return _isQObject; }
134 bool isQObject() { return _isQObject; }
135
135
136 //! returns if the class is a CPP wrapper
136 //! returns if the class is a CPP wrapper
137 bool isCPPWrapper() { return !_isQObject; }
137 bool isCPPWrapper() { return !_isQObject; }
138
138
139 //! get the meta object
139 //! get the meta object
140 const QMetaObject* metaObject() { return _meta; }
140 const QMetaObject* metaObject() { return _meta; }
141
141
142 //! set the meta object, this will reset the caching
142 //! set the meta object, this will reset the caching
143 void setMetaObject(const QMetaObject* meta);
143 void setMetaObject(const QMetaObject* meta);
144
144
145 //! returns if this class inherits from the given classname
145 //! returns if this class inherits from the given classname
146 bool inherits(const char* classname);
146 bool inherits(const char* classname);
147
147
148 //! returns if this class inherits from the given classinfo
148 //! returns if this class inherits from the given classinfo
149 bool inherits(PythonQtClassInfo* info);
149 bool inherits(PythonQtClassInfo* info);
150
150
151 //! casts the given \c ptr to an object of type \c classname, returns the new pointer
151 //! casts the given \c ptr to an object of type \c classname, returns the new pointer
152 //! which might be different to \c ptr due to C++ multiple inheritance
152 //! which might be different to \c ptr due to C++ multiple inheritance
153 //! (if the cast is not possible or if ptr is NULL, NULL is returned)
153 //! (if the cast is not possible or if ptr is NULL, NULL is returned)
154 void* castTo(void* ptr, const char* classname);
154 void* castTo(void* ptr, const char* classname);
155
155
156 //! get help string for the metaobject
156 //! get help string for the metaobject
157 QString help();
157 QString help();
158
158
159 //! get list of all properties (on QObjects only, otherwise the list is empty)
159 //! get list of all properties (on QObjects only, otherwise the list is empty)
160 QStringList propertyList();
160 QStringList propertyList();
161
161
162 //! get list of all members
162 //! get list of all members
163 QStringList memberList(bool metaOnly = false);
163 QStringList memberList(bool metaOnly = false);
164
164
165 //! get the meta type id of this class (only valid for isCPPWrapper() == true)
165 //! get the meta type id of this class (only valid for isCPPWrapper() == true)
166 int metaTypeId() { return _metaTypeId; }
166 int metaTypeId() { return _metaTypeId; }
167
167
168 //! set an additional decorator provider that offers additional decorator slots for this class
168 //! set an additional decorator provider that offers additional decorator slots for this class
169 void setDecoratorProvider(PythonQtQObjectCreatorFunctionCB* cb) { _decoratorProviderCB = cb; _decoratorProvider = NULL; }
169 void setDecoratorProvider(PythonQtQObjectCreatorFunctionCB* cb) { _decoratorProviderCB = cb; _decoratorProvider = NULL; }
170
170
171 //! get the decorator qobject instance
171 //! get the decorator qobject instance
172 QObject* decorator();
172 QObject* decorator();
173
173
174 //! add the parent class info of a CPP object
174 //! add the parent class info of a CPP object
175 void addParentClass(const ParentClassInfo& info) { _parentClasses.append(info); }
175 void addParentClass(const ParentClassInfo& info) { _parentClasses.append(info); }
176
176
177 //! check if the special method "py_hasOwner" is implemented and if it returns false, which means that the object may be destroyed
177 //! check if the special method "py_hasOwner" is implemented and if it returns false, which means that the object may be destroyed
178 bool hasOwnerMethodButNoOwner(void* object);
178 bool hasOwnerMethodButNoOwner(void* object);
179
179
180 //! set the associated PythonQtClassWrapper (which handles instance creation of this type)
180 //! set the associated PythonQtClassWrapper (which handles instance creation of this type)
181 void setPythonQtClassWrapper(PyObject* obj) { _pythonQtClassWrapper = obj; }
181 void setPythonQtClassWrapper(PyObject* obj) { _pythonQtClassWrapper = obj; }
182
182
183 //! get the associated PythonQtClassWrapper (which handles instance creation of this type)
183 //! get the associated PythonQtClassWrapper (which handles instance creation of this type)
184 PyObject* pythonQtClassWrapper() { return _pythonQtClassWrapper; }
184 PyObject* pythonQtClassWrapper() { return _pythonQtClassWrapper; }
185
185
186 //! set the shell set instance wrapper cb
186 //! set the shell set instance wrapper cb
187 void setShellSetInstanceWrapperCB(PythonQtShellSetInstanceWrapperCB* cb) {
187 void setShellSetInstanceWrapperCB(PythonQtShellSetInstanceWrapperCB* cb) {
188 _shellSetInstanceWrapperCB = cb;
188 _shellSetInstanceWrapperCB = cb;
189 }
189 }
190
190
191 //! get the shell set instance wrapper cb
191 //! get the shell set instance wrapper cb
192 PythonQtShellSetInstanceWrapperCB* shellSetInstanceWrapperCB() {
192 PythonQtShellSetInstanceWrapperCB* shellSetInstanceWrapperCB() {
193 return _shellSetInstanceWrapperCB;
193 return _shellSetInstanceWrapperCB;
194 }
194 }
195
195
196 //! add a handler for polymorphic downcasting
196 //! add a handler for polymorphic downcasting
197 void addPolymorphicHandler(PythonQtPolymorphicHandlerCB* cb) { _polymorphicHandlers.append(cb); }
197 void addPolymorphicHandler(PythonQtPolymorphicHandlerCB* cb) { _polymorphicHandlers.append(cb); }
198
198
199 //! cast the pointer down in the class hierarchy if a polymorphic handler allows to do that
199 //! cast the pointer down in the class hierarchy if a polymorphic handler allows to do that
200 void* castDownIfPossible(void* ptr, PythonQtClassInfo** resultClassInfo);
200 void* castDownIfPossible(void* ptr, PythonQtClassInfo** resultClassInfo);
201
201
202 //! returns if the localScope has an enum of that type name or if the enum contains a :: scope, if that class contails the enum
202 //! returns if the localScope has an enum of that type name or if the enum contains a :: scope, if that class contails the enum
203 static PyObject* findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool* isLocalEnum = NULL);
203 static PyObject* findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool* isLocalEnum = NULL);
204
204
205 private:
205 private:
206 void createEnumWrappers();
206 void createEnumWrappers();
207 void createEnumWrappers(const QMetaObject* meta);
207 void createEnumWrappers(const QMetaObject* meta);
208 PyObject* findEnumWrapper(const char* name);
208 PyObject* findEnumWrapper(const char* name);
209
209
210 //! clear all cached members
210 //! clear all cached members
211 void clearCachedMembers();
211 void clearCachedMembers();
212
212
213 void* recursiveCastDownIfPossible(void* ptr, char** resultClassName);
213 void* recursiveCastDownIfPossible(void* ptr, char** resultClassName);
214
214
215 PythonQtSlotInfo* findDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset);
215 PythonQtSlotInfo* findDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset);
216 void listDecoratorSlotsFromDecoratorProvider(QStringList& list, bool metaOnly);
216 void listDecoratorSlotsFromDecoratorProvider(QStringList& list, bool metaOnly);
217 PythonQtSlotInfo* recursiveFindDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset);
217 PythonQtSlotInfo* recursiveFindDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset);
218
218
219 void recursiveCollectClassInfos(QList<PythonQtClassInfo*>& classInfoObjects);
219 void recursiveCollectClassInfos(QList<PythonQtClassInfo*>& classInfoObjects);
220 void recursiveCollectDecoratorObjects(QList<QObject*>& decoratorObjects);
220 void recursiveCollectDecoratorObjects(QList<QObject*>& decoratorObjects);
221
221
222 bool lookForPropertyAndCache(const char* memberName);
222 bool lookForPropertyAndCache(const char* memberName);
223 bool lookForMethodAndCache(const char* memberName);
223 bool lookForMethodAndCache(const char* memberName);
224 bool lookForEnumAndCache(const QMetaObject* m, const char* memberName);
224 bool lookForEnumAndCache(const QMetaObject* m, const char* memberName);
225
225
226 PythonQtSlotInfo* findDecoratorSlots(const char* memberName, int memberNameLen, PythonQtSlotInfo* tail, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset);
226 PythonQtSlotInfo* findDecoratorSlots(const char* memberName, int memberNameLen, PythonQtSlotInfo* tail, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset);
227 int findCharOffset(const char* sigStart, char someChar);
227 int findCharOffset(const char* sigStart, char someChar);
228
228
229 QHash<QByteArray, PythonQtMemberInfo> _cachedMembers;
229 QHash<QByteArray, PythonQtMemberInfo> _cachedMembers;
230
230
231 PythonQtSlotInfo* _constructors;
231 PythonQtSlotInfo* _constructors;
232 PythonQtSlotInfo* _destructor;
232 PythonQtSlotInfo* _destructor;
233 QList<PythonQtSlotInfo*> _decoratorSlots;
233 QList<PythonQtSlotInfo*> _decoratorSlots;
234
234
235 QList<PythonQtObjectPtr> _enumWrappers;
235 QList<PythonQtObjectPtr> _enumWrappers;
236
236
237 const QMetaObject* _meta;
237 const QMetaObject* _meta;
238
238
239 QByteArray _wrappedClassName;
239 QByteArray _wrappedClassName;
240 QList<ParentClassInfo> _parentClasses;
240 QList<ParentClassInfo> _parentClasses;
241
241
242 QList<PythonQtPolymorphicHandlerCB*> _polymorphicHandlers;
242 QList<PythonQtPolymorphicHandlerCB*> _polymorphicHandlers;
243
243
244 QObject* _decoratorProvider;
244 QObject* _decoratorProvider;
245 PythonQtQObjectCreatorFunctionCB* _decoratorProviderCB;
245 PythonQtQObjectCreatorFunctionCB* _decoratorProviderCB;
246
246
247 PyObject* _pythonQtClassWrapper;
247 PyObject* _pythonQtClassWrapper;
248
248
249 PythonQtShellSetInstanceWrapperCB* _shellSetInstanceWrapperCB;
249 PythonQtShellSetInstanceWrapperCB* _shellSetInstanceWrapperCB;
250
250
251 int _metaTypeId;
251 int _metaTypeId;
252 int _typeSlots;
252 int _typeSlots;
253
253
254 bool _isQObject;
254 bool _isQObject;
255 bool _enumsCreated;
255 bool _enumsCreated;
256
256
257 };
257 };
258
258
259 //---------------------------------------------------------------
259 //---------------------------------------------------------------
260
260
261
261
262 #endif
262 #endif
@@ -1,509 +1,512
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 PythonQt Overview
49 \mainpage PythonQt Overview
50 \endif
50 \endif
51
51
52 \section Introduction
52 \section Introduction
53
53
54 \b PythonQt is a dynamic Python (http://www.python.org) binding for the Qt framework (http://qt.nokia.com).
54 \b PythonQt is a dynamic Python (http://www.python.org) binding for the Qt framework (http://qt.nokia.com).
55 It offers an easy way to embed the Python scripting language into
55 It offers an easy way to embed the Python scripting language into
56 your C++ Qt applications. It makes heavy use of the QMetaObject system and thus requires Qt 4.x.
56 your C++ Qt applications. It makes heavy use of the QMetaObject system and thus requires Qt 4.x.
57
57
58 The focus of PythonQt is on embedding Python into an existing C++ application, not on writing the whole
58 The focus of PythonQt is on embedding Python into an existing C++ application, not on writing the whole
59 application completely in Python. If you want to write your whole application in Python,
59 application completely in Python. If you want to write your whole application in Python,
60 you should use <a href="http://www.riverbankcomputing.co.uk/pyqt/">PyQt</a> or <a href="http://www.pyside.org">PySide</a> instead.
60 you should use <a href="http://www.riverbankcomputing.co.uk/pyqt/">PyQt</a> or <a href="http://www.pyside.org">PySide</a> instead.
61
61
62 If you are looking for a simple way to embed Python objects into your C++/Qt Application
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 Image Processing and Visualization platform MeVisLab (http://www.mevislab.de)
67 scriptable from Python.
67 scriptable from Python.
68
68
69 \section Download
69 \section Download
70
70
71 PythonQt is hosted on SourceForge at http://sourceforge.net/projects/pythonqt , you can access it via SVN
71 PythonQt is hosted on SourceForge at http://sourceforge.net/projects/pythonqt , you can access it via SVN
72 or download a tarball.
72 or download a tarball.
73
73
74 \section Licensing
74 \section Licensing
75
75
76 PythonQt is distributed under the LGPL license, so it pairs well with the LGPL of the Qt 4.5 release and allows
76 PythonQt is distributed under the LGPL license, so it pairs well with the LGPL of the Qt 4.5 release and allows
77 to be used in commercial applications when following the LGPL 2.1 obligations.
77 to be used in commercial applications when following the LGPL 2.1 obligations.
78
78
79 \section LicensingWrapper Licensing of Wrapper Generator
79 \section LicensingWrapper Licensing of Wrapper Generator
80
80
81 The build system of PythonQt makes use of a modified version of the LGPL'ed QtScript generator,
81 The build system of PythonQt makes use of a modified version of the LGPL'ed QtScript generator,
82 located in the "generator" directory.
82 located in the "generator" directory.
83
83
84 See http://qt.gitorious.org/qt-labs/qtscriptgenerator for details on the original project.
84 See http://qt.gitorious.org/qt-labs/qtscriptgenerator for details on the original project.
85 Thanks a lot to the QtJambi guys and the QtScript Generator project for the C++ parser and
85 Thanks a lot to the QtJambi guys and the QtScript Generator project for the C++ parser and
86 Qt typesystem files!
86 Qt typesystem files!
87
87
88 The PythonQt wrappers generated by the generator located in the "generated_cpp" directory are free to be used without any licensing restrictions.
88 The PythonQt wrappers generated by the generator located in the "generated_cpp" directory are free to be used without any licensing restrictions.
89
89
90 The generated wrappers are pre-generated and checked-in for Qt 4.6.1, so you only need to build and run the
90 The generated wrappers are pre-generated and checked-in for Qt 4.6.1, so you only need to build and run the
91 generator when you want to build additional wrappers or you want to upgrade/downgrade to another Qt version.
91 generator when you want to build additional wrappers or you want to upgrade/downgrade to another Qt version.
92 You may use the generator to generate C++ bindings for your own C++ classes (e.g., to make them inheritable in Python),
92 You may use the generator to generate C++ bindings for your own C++ classes (e.g., to make them inheritable in Python),
93 , but this is currently not documented and involves creating your own typesystem files (although the Qt Jambi examples might help you).
93 , but this is currently not documented and involves creating your own typesystem files (although the Qt Jambi examples might help you).
94
94
95 \section Features
95 \section Features
96
96
97 The following are the built-in features of the PythonQt library:
97 The following are the built-in features of the PythonQt library:
98
98
99 - Access all \b slots, \b properties, children and registered enums of any QObject derived class from Python
99 - Access all \b slots, \b properties, children and registered enums of any QObject derived class from Python
100 - Connecting Qt Signals to Python functions (both from within Python and from C++)
100 - Connecting Qt Signals to Python functions (both from within Python and from C++)
101 - Easy wrapping of Python objects from C++ with smart, reference-counting PythonQtObjectPtr.
101 - Easy wrapping of Python objects from C++ with smart, reference-counting PythonQtObjectPtr.
102 - Convenient conversions to/from QVariant for PythonQtObjectPtr.
102 - Convenient conversions to/from QVariant for PythonQtObjectPtr.
103 - Wrapping of C++ objects (which are not derived from QObject) via PythonQtCppWrapperFactory
103 - Wrapping of C++ objects (which are not derived from QObject) via PythonQtCppWrapperFactory
104 - Extending C++ and QObject derived classes with additional slots, static methods and constructors (see Decorators)
104 - Extending C++ and QObject derived classes with additional slots, static methods and constructors (see Decorators)
105 - StdOut/Err redirection to Qt signals instead of cout
105 - StdOut/Err redirection to Qt signals instead of cout
106 - Interface for creating your own \c import replacement, so that Python scripts can be e.g. signed/verified before they are executed (PythonQtImportFileInterface)
106 - Interface for creating your own \c import replacement, so that Python scripts can be e.g. signed/verified before they are executed (PythonQtImportFileInterface)
107 - Mapping of plain-old-datatypes and ALL QVariant types to and from Python
107 - Mapping of plain-old-datatypes and ALL QVariant types to and from Python
108 - Support for wrapping of user QVariant types which are registerd via QMetaType
108 - Support for wrapping of user QVariant types which are registerd via QMetaType
109 - Support for Qt namespace (with all enumerators)
109 - Support for Qt namespace (with all enumerators)
110 - All PythonQt wrapped objects support the dir() statement, so that you can see easily which attributes a QObject, CPP object or QVariant has
110 - All PythonQt wrapped objects support the dir() statement, so that you can see easily which attributes a QObject, CPP object or QVariant has
111 - 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)
111 - 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)
112 - 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)
112 - 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)
113 - 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)
113 - 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)
114 - Deriving C++ objects from Python and overwriting virtual method with a Python implementation (requires usage of wrapper generator or manual work!)
114 - Deriving C++ objects from Python and overwriting virtual method with a Python implementation (requires usage of wrapper generator or manual work!)
115 - Extensible handler for Python/C++ conversion of complex types, e.g. mapping of QVector<SomeObject> to/from a Python array
115 - Extensible handler for Python/C++ conversion of complex types, e.g. mapping of QVector<SomeObject> to/from a Python array
116 - 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)
116
117
117 \section FeaturesQtAll Features (with PythonQt_QtAll linked in)
118 \section FeaturesQtAll Features (with PythonQt_QtAll linked in)
118
119
119 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.
120 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.
120 This offers the following features:
121 This offers the following features:
121
122
122 - Complete Qt API wrapped and accessible
123 - Complete Qt API wrapped and accessible
123 - The following modules are available as submodules of the PythonQt module:
124 - The following modules are available as submodules of the PythonQt module:
124 - QtCore
125 - QtCore
125 - QtGui
126 - QtGui
126 - QtNetwork
127 - QtNetwork
127 - QtOpenGL
128 - QtOpenGL
128 - QtSql
129 - QtSql
129 - QtSvg
130 - QtSvg
130 - QtUiTools
131 - QtUiTools
131 - QtWebKit
132 - QtWebKit
132 - QtXml
133 - QtXml
133 - QtXmlPatterns
134 - (QtXmlPatterns, QtScript, QtHelp, phonon, assistant, designer are currently not supported, this would require some additional effort on the code generator)
134 - (phonon, QtHelp, assistant, designer are currently not supported, this would require some additional effort on the code generator)
135 - 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
135 - 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
136 - Any Qt class that has virtual methods can be easily derived from Python and the virtual methods can be reimplemented in Python
136 - 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!)
137 - Polymorphic downcasting on QEvent, QGraphicsItem, QStyleOption, ...
137 - Polymorphic downcasting on QEvent, QGraphicsItem, QStyleOption, ...
138 - Multiple inheritance support (e.g., QGraphicsTextItem is a QObject AND a QGraphicsItem, PythonQt will handle this well)
138 - Multiple inheritance support (e.g., QGraphicsTextItem is a QObject AND a QGraphicsItem, PythonQt will handle this well)
139
139
140 \section Comparision Comparision with PyQt/PySide
140 \section Comparision Comparision with PyQt/PySide
141
141
142 - 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
142 - 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
143 - 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
143 - 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
144 - 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)
144 - 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)
145 - PythonQt does not support instanceof checks for Qt classes, except for the exact match and derived Python classes
145 - PythonQt currently does not support instanceof checks for Qt classes, except for the exact match and derived Python classes
146 - QObject.emit to emit Qt signals from Python is not yet implemented but PythonQt allows to just emit a signal by calling it
146 - 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
147 - PythonQt does not (yet) offer to add new signals to Python/C++ objects
147 - 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)
148 - 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)
148 - 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)
149 - QStrings are always converted to unicode Python objects (PyQt returns QString instead), we prefered to return Python strings.
149 - QStrings are always converted to unicode Python objects, QByteArray always stays a QByteArray and can be converted using str()
150 - 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.
151 - 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).
150 - Probably there are lots of details that differ, I do not know PyQt that well to list them all.
152 - Probably there are lots of details that differ, I do not know PyQt that well to list them all.
153 - 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).
151
154
152 \section Interface
155 \section Interface
153
156
154 The main interface to PythonQt is the PythonQt singleton.
157 The main interface to PythonQt is the PythonQt singleton.
155 PythonQt needs to be initialized via PythonQt::init() once.
158 PythonQt needs to be initialized via PythonQt::init() once.
156 Afterwards you communicate with the singleton via PythonQt::self().
159 Afterwards you communicate with the singleton via PythonQt::self().
157 PythonQt offers a complete Qt binding, which
160 PythonQt offers a complete Qt binding, which
158 needs to be enabled via PythonQt_QtAll::init().
161 needs to be enabled via PythonQt_QtAll::init().
159
162
160
163
161 \section Datatype Datatype Mapping
164 \section Datatype Datatype Mapping
162
165
163 The following table shows the mapping between Python and Qt objects:
166 The following table shows the mapping between Python and Qt objects:
164 <table>
167 <table>
165 <tr><th>Qt/C++</th><th>Python</th></tr>
168 <tr><th>Qt/C++</th><th>Python</th></tr>
166 <tr><td>bool</td><td>bool</td></tr>
169 <tr><td>bool</td><td>bool</td></tr>
167 <tr><td>double</td><td>float</td></tr>
170 <tr><td>double</td><td>float</td></tr>
168 <tr><td>float</td><td>float</td></tr>
171 <tr><td>float</td><td>float</td></tr>
169 <tr><td>char/uchar,int/uint,short,ushort,QChar</td><td>integer</td></tr>
172 <tr><td>char/uchar,int/uint,short,ushort,QChar</td><td>integer</td></tr>
170 <tr><td>long</td><td>integer</td></tr>
173 <tr><td>long</td><td>integer</td></tr>
171 <tr><td>ulong,longlong,ulonglong</td><td>long</td></tr>
174 <tr><td>ulong,longlong,ulonglong</td><td>long</td></tr>
172 <tr><td>QString</td><td>unicode string</td></tr>
175 <tr><td>QString</td><td>unicode string</td></tr>
173 <tr><td>QByteArray</td><td>str</td></tr>
176 <tr><td>QByteArray</td><td>str</td></tr>
174 <tr><td>char*</td><td>str</td></tr>
177 <tr><td>char*</td><td>str</td></tr>
175 <tr><td>QStringList</td><td>tuple of unicode strings</td></tr>
178 <tr><td>QStringList</td><td>tuple of unicode strings</td></tr>
176 <tr><td>QVariantList</td><td>tuple of objects</td></tr>
179 <tr><td>QVariantList</td><td>tuple of objects</td></tr>
177 <tr><td>QVariantMap</td><td>dict of objects</td></tr>
180 <tr><td>QVariantMap</td><td>dict of objects</td></tr>
178 <tr><td>QVariant</td><td>depends on type, see below</td></tr>
181 <tr><td>QVariant</td><td>depends on type, see below</td></tr>
179 <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>
182 <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>
180 <tr><td>OwnRegisteredMetaType</td><td>C++ wrapper, optionally with additional information/wrapping provided by registerCPPClass()</td></tr>
183 <tr><td>OwnRegisteredMetaType</td><td>C++ wrapper, optionally with additional information/wrapping provided by registerCPPClass()</td></tr>
181 <tr><td>QList<AnyObject*></td><td>converts to a list of CPP wrappers</td></tr>
184 <tr><td>QList<AnyObject*></td><td>converts to a list of CPP wrappers</td></tr>
182 <tr><td>EnumType</td><td>integer (all enums that are known via the moc and the Qt namespace are supported)</td></tr>
185 <tr><td>EnumType</td><td>integer (all enums that are known via the moc and the Qt namespace are supported)</td></tr>
183 <tr><td>QObject (and derived classes)</td><td>QObject wrapper</td></tr>
186 <tr><td>QObject (and derived classes)</td><td>QObject wrapper</td></tr>
184 <tr><td>C++ object</td><td>CPP wrapper, either wrapped via PythonQtCppWrapperFactory or just decorated with decorators</td></tr>
187 <tr><td>C++ object</td><td>CPP wrapper, either wrapped via PythonQtCppWrapperFactory or just decorated with decorators</td></tr>
185 <tr><td>PyObject</td><td>PyObject</td></tr>
188 <tr><td>PyObject</td><td>PyObject</td></tr>
186 </table>
189 </table>
187
190
188 PyObject is passed as simple pointer, which allows to pass/return any Python Object directly to/from
191 PyObject is passed as simple pointer, which allows to pass/return any Python Object directly to/from
189 a Qt slot.
192 a Qt slot.
190 QVariants are mapped recursively as given above, e.g. a dictionary can
193 QVariants are mapped recursively as given above, e.g. a dictionary can
191 contain lists of dictionaries of doubles.
194 contain lists of dictionaries of doubles.
192 For example a QVariant of type "String" is mapped to a python unicode string.
195 For example a QVariant of type "String" is mapped to a python unicode string.
193 All Qt QVariant types are implemented, PythonQt supports the complete Qt API for these object.
196 All Qt QVariant types are implemented, PythonQt supports the complete Qt API for these object.
194
197
195 \section QObject QObject Wrapping
198 \section QObject QObject Wrapping
196
199
197 All classes derived from QObject are automatically wrapped with a python wrapper class
200 All classes derived from QObject are automatically wrapped with a python wrapper class
198 when they become visible to the Python interpreter. This can happen via
201 when they become visible to the Python interpreter. This can happen via
199 - the PythonQt::addObject() method
202 - the PythonQt::addObject() method
200 - when a Qt \b slot returns a QObject derived object to python
203 - when a Qt \b slot returns a QObject derived object to python
201 - when a Qt \b signal contains a QObject and is connected to a python function
204 - when a Qt \b signal contains a QObject and is connected to a python function
202
205
203 It is important that you call PythonQt::registerClass() for any QObject derived class
206 It is important that you call PythonQt::registerClass() for any QObject derived class
204 that may become visible to Python, except when you add it via PythonQt::addObject().
207 that may become visible to Python, except when you add it via PythonQt::addObject().
205 This will register the complete parent hierachy of the registered class, so that
208 This will register the complete parent hierachy of the registered class, so that
206 when you register e.g. a QPushButton, QWidget will be registered as well (and all intermediate
209 when you register e.g. a QPushButton, QWidget will be registered as well (and all intermediate
207 parents).
210 parents).
208
211
209 From Python, you can talk to the returned QObjects in a natural way by calling
212 From Python, you can talk to the returned QObjects in a natural way by calling
210 their slots and receiving the return values. You can also read/write all
213 their slots and receiving the return values. You can also read/write all
211 properties of the objects as if they where normal python properties.
214 properties of the objects as if they where normal python properties.
212
215
213 In addition to this, the wrapped objects support
216 In addition to this, the wrapped objects support
214 - className() - returns a string that reprents the classname of the QObject
217 - className() - returns a string that reprents the classname of the QObject
215 - help() - shows all properties, slots, enums, decorator slots and constructors of the object, in a printable form
218 - help() - shows all properties, slots, enums, decorator slots and constructors of the object, in a printable form
216 - delete() - deletes the object (use with care, especially if you passed the ownership to C++)
219 - delete() - deletes the object (use with care, especially if you passed the ownership to C++)
217 - connect(signal, function) - connect the signal of the given object to a python function
220 - connect(signal, function) - connect the signal of the given object to a python function
218 - connect(signal, qobject, slot) - connect the signal of the given object to a slot of another QObject
221 - connect(signal, qobject, slot) - connect the signal of the given object to a slot of another QObject
219 - disconnect(signal, function) - disconnect the signal of the given object from a python function
222 - disconnect(signal, function) - disconnect the signal of the given object from a python function
220 - disconnect(signal, qobject, slot) - disconnect the signal of the given object from a slot of another QObject
223 - disconnect(signal, qobject, slot) - disconnect the signal of the given object from a slot of another QObject
221 - children() - returns the children of the object
224 - children() - returns the children of the object
222 - setParent(QObject) - set the parent
225 - setParent(QObject) - set the parent
223 - QObject* parent() - get the parent
226 - QObject* parent() - get the parent
224
227
225 The below example shows how to connect signals in Python:
228 The below example shows how to connect signals in Python:
226
229
227 \code
230 \code
228 # define a signal handler function
231 # define a signal handler function
229 def someFunction(flag):
232 def someFunction(flag):
230 print flag
233 print flag
231
234
232 # button1 is a QPushButton that has been added to Python via addObject()
235 # button1 is a QPushButton that has been added to Python via addObject()
233 # connect the clicked signal to a python function:
236 # connect the clicked signal to a python function:
234 button1.connect("clicked(bool)", someFunction)
237 button1.connect("clicked(bool)", someFunction)
235
238
236 \endcode
239 \endcode
237
240
238 \section CPP CPP Wrapping
241 \section CPP CPP Wrapping
239
242
240 You can create dedicated wrapper QObjects for any C++ class. This is done by deriving from PythonQtCppWrapperFactory
243 You can create dedicated wrapper QObjects for any C++ class. This is done by deriving from PythonQtCppWrapperFactory
241 and adding your factory via addWrapperFactory().
244 and adding your factory via addWrapperFactory().
242 Whenever PythonQt encounters a CPP pointer (e.g. on a slot or signal)
245 Whenever PythonQt encounters a CPP pointer (e.g. on a slot or signal)
243 and it does not known it as a QObject derived class, it will create a generic CPP wrapper. So even unknown C++ objects
246 and it does not known it as a QObject derived class, it will create a generic CPP wrapper. So even unknown C++ objects
244 can be passed through Python. If the wrapper factory supports the CPP class, a QObject wrapper will be created for each
247 can be passed through Python. If the wrapper factory supports the CPP class, a QObject wrapper will be created for each
245 instance that enters Python. An alternative to a complete wrapper via the wrapper factory are decorators, see \ref Decorators
248 instance that enters Python. An alternative to a complete wrapper via the wrapper factory are decorators, see \ref Decorators
246
249
247 \section MetaObject Meta Object/Class access
250 \section MetaObject Meta Object/Class access
248
251
249 For each known C++ class, PythonQt provides a Python class. These classes are visible
252 For each known C++ class, PythonQt provides a Python class. These classes are visible
250 inside of the "PythonQt" python module or in subpackages if a package is given when the class is registered.
253 inside of the "PythonQt" python module or in subpackages if a package is given when the class is registered.
251
254
252 A Meta class supports:
255 A Meta class supports:
253
256
254 - access to all declared enum values
257 - access to all declared enum values
255 - constructors
258 - constructors
256 - static methods
259 - static methods
257 - unbound non-static methods
260 - unbound non-static methods
258 - help() and className()
261 - help() and className()
259
262
260 From within Python, you can import the module "PythonQt" to access these classes and the Qt namespace.
263 From within Python, you can import the module "PythonQt" to access these classes and the Qt namespace.
261
264
262 \code
265 \code
263 from PythonQt import QtCore
266 from PythonQt import QtCore
264
267
265 # namespace access:
268 # namespace access:
266 print QtCore.Qt.AlignLeft
269 print QtCore.Qt.AlignLeft
267
270
268 # constructors
271 # constructors
269 a = QtCore.QSize(12,13)
272 a = QtCore.QSize(12,13)
270 b = QtCore.QFont()
273 b = QtCore.QFont()
271
274
272 # static method
275 # static method
273 QtCore.QDate.currentDate()
276 QtCore.QDate.currentDate()
274
277
275 # enum value
278 # enum value
276 QtCore.QFont.UltraCondensed
279 QtCore.QFont.UltraCondensed
277
280
278 \endcode
281 \endcode
279
282
280 \section Decorators Decorator slots
283 \section Decorators Decorator slots
281
284
282 PythonQt introduces a new generic approach to extend any wrapped QObject or CPP object with
285 PythonQt introduces a new generic approach to extend any wrapped QObject or CPP object with
283
286
284 - constructors
287 - constructors
285 - destructors (for CPP objects)
288 - destructors (for CPP objects)
286 - additional slots
289 - additional slots
287 - static slots (callable on both the Meta object and the instances)
290 - static slots (callable on both the Meta object and the instances)
288
291
289 The idea behind decorators is that we wanted to make it as easy as possible to extend
292 The idea behind decorators is that we wanted to make it as easy as possible to extend
290 wrapped objects. Since we already have an implementation for invoking any Qt Slot from
293 wrapped objects. Since we already have an implementation for invoking any Qt Slot from
291 Python, it looked promising to use this approach for the extension of wrapped objects as well.
294 Python, it looked promising to use this approach for the extension of wrapped objects as well.
292 This avoids that the PythonQt user needs to care about how Python arguments are mapped from/to
295 This avoids that the PythonQt user needs to care about how Python arguments are mapped from/to
293 Qt when he wants to create static methods, constructors and additional member functions.
296 Qt when he wants to create static methods, constructors and additional member functions.
294
297
295 The basic idea about decorators is to create a QObject derived class that implements slots
298 The basic idea about decorators is to create a QObject derived class that implements slots
296 which take one of the above roles (e.g. constructor, destructor etc.) via a naming convention.
299 which take one of the above roles (e.g. constructor, destructor etc.) via a naming convention.
297 These slots are then assigned to other classes via the naming convention.
300 These slots are then assigned to other classes via the naming convention.
298
301
299 - 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)
302 - 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)
300 - void delete_SomeClassName(SomeClassName* o) - defines a destructor, which should delete the passed in object o
303 - void delete_SomeClassName(SomeClassName* o) - defines a destructor, which should delete the passed in object o
301 - anything static_SomeClassName_someMethodName(...) - defines a static method that is callable on instances and the meta class
304 - anything static_SomeClassName_someMethodName(...) - defines a static method that is callable on instances and the meta class
302 - 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.
305 - 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.
303
306
304 The below example shows all kinds of decorators in action:
307 The below example shows all kinds of decorators in action:
305
308
306 \code
309 \code
307
310
308 // an example CPP object
311 // an example CPP object
309 class YourCPPObject {
312 class YourCPPObject {
310 public:
313 public:
311 YourCPPObject(int arg1, float arg2) { a = arg1; b = arg2; }
314 YourCPPObject(int arg1, float arg2) { a = arg1; b = arg2; }
312
315
313 float doSomething(int arg1) { return arg1*a*b; };
316 float doSomething(int arg1) { return arg1*a*b; };
314
317
315 private:
318 private:
316
319
317 int a;
320 int a;
318 float b;
321 float b;
319 };
322 };
320
323
321 // an example decorator
324 // an example decorator
322 class ExampleDecorator : public QObject
325 class ExampleDecorator : public QObject
323 {
326 {
324 Q_OBJECT
327 Q_OBJECT
325
328
326 public slots:
329 public slots:
327 // add a constructor to QSize that takes a QPoint
330 // add a constructor to QSize that takes a QPoint
328 QSize* new_QSize(const QPoint& p) { return new QSize(p.x(), p.y()); }
331 QSize* new_QSize(const QPoint& p) { return new QSize(p.x(), p.y()); }
329
332
330 // add a constructor for QPushButton that takes a text and a parent widget
333 // add a constructor for QPushButton that takes a text and a parent widget
331 QPushButton* new_QPushButton(const QString& text, QWidget* parent=NULL) { return new QPushButton(text, parent); }
334 QPushButton* new_QPushButton(const QString& text, QWidget* parent=NULL) { return new QPushButton(text, parent); }
332
335
333 // add a constructor for a CPP object
336 // add a constructor for a CPP object
334 YourCPPObject* new_YourCPPObject(int arg1, float arg2) { return new YourCPPObject(arg1, arg2); }
337 YourCPPObject* new_YourCPPObject(int arg1, float arg2) { return new YourCPPObject(arg1, arg2); }
335
338
336 // add a destructor for a CPP object
339 // add a destructor for a CPP object
337 void delete_YourCPPObject(YourCPPObject* obj) { delete obj; }
340 void delete_YourCPPObject(YourCPPObject* obj) { delete obj; }
338
341
339 // add a static method to QWidget
342 // add a static method to QWidget
340 QWidget* static_QWidget_mouseGrabber() { return QWidget::mouseGrabber(); }
343 QWidget* static_QWidget_mouseGrabber() { return QWidget::mouseGrabber(); }
341
344
342 // add an additional slot to QWidget (make move() callable, which is not declared as a slot in QWidget)
345 // add an additional slot to QWidget (make move() callable, which is not declared as a slot in QWidget)
343 void move(QWidget* w, const QPoint& p) { w->move(p); }
346 void move(QWidget* w, const QPoint& p) { w->move(p); }
344
347
345 // add an additional slot to QWidget, overloading the above move method
348 // add an additional slot to QWidget, overloading the above move method
346 void move(QWidget* w, int x, int y) { w->move(x,y); }
349 void move(QWidget* w, int x, int y) { w->move(x,y); }
347
350
348 // add a method to your own CPP object
351 // add a method to your own CPP object
349 int doSomething(YourCPPObject* obj, int arg1) { return obj->doSomething(arg1); }
352 int doSomething(YourCPPObject* obj, int arg1) { return obj->doSomething(arg1); }
350 };
353 };
351
354
352 ...
355 ...
353
356
354 PythonQt::self()->addDecorators(new ExampleDecorator());
357 PythonQt::self()->addDecorators(new ExampleDecorator());
355 PythonQt::self()->registerCPPClass("YourCPPObject");
358 PythonQt::self()->registerCPPClass("YourCPPObject");
356
359
357 \endcode
360 \endcode
358
361
359 After you have registered an instance of the above ExampleDecorator, you can do the following from Python
362 After you have registered an instance of the above ExampleDecorator, you can do the following from Python
360 (all these calls are mapped to the above decorator slots):
363 (all these calls are mapped to the above decorator slots):
361
364
362 \code
365 \code
363 from PythonQt import QtCore, QtGui, YourCPPObject
366 from PythonQt import QtCore, QtGui, YourCPPObject
364
367
365 # call our new constructor of QSize
368 # call our new constructor of QSize
366 size = QtCore.QSize(QPoint(1,2));
369 size = QtCore.QSize(QPoint(1,2));
367
370
368 # call our new QPushButton constructor
371 # call our new QPushButton constructor
369 button = QtGui.QPushButton("sometext");
372 button = QtGui.QPushButton("sometext");
370
373
371 # call the move slot (overload1)
374 # call the move slot (overload1)
372 button.move(QPoint(0,0))
375 button.move(QPoint(0,0))
373
376
374 # call the move slot (overload2)
377 # call the move slot (overload2)
375 button.move(0,0)
378 button.move(0,0)
376
379
377 # call the static method
380 # call the static method
378 grabber = QtGui.QWidget.mouseWrapper();
381 grabber = QtGui.QWidget.mouseWrapper();
379
382
380 # create a CPP object via constructor
383 # create a CPP object via constructor
381 yourCpp = YourCPPObject(1,11.5)
384 yourCpp = YourCPPObject(1,11.5)
382
385
383 # call the wrapped method on CPP object
386 # call the wrapped method on CPP object
384 print yourCpp.doSomething(1);
387 print yourCpp.doSomething(1);
385
388
386 # destructor will be called:
389 # destructor will be called:
387 yourCpp = None
390 yourCpp = None
388
391
389 \endcode
392 \endcode
390
393
391 \section Building
394 \section Building
392
395
393 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.
396 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.
394 To compile PythonQt, you will need a python developer installation which includes Python's header files and
397 To compile PythonQt, you will need a python developer installation which includes Python's header files and
395 the python2x.[lib | dll | so | dynlib].
398 the python2x.[lib | dll | so | dynlib].
396 The build scripts a currently set to use Python 2.6.
399 The build scripts a currently set to use Python 2.6.
397 You may need to tweak the \b build/python.prf file to set the correct Python includes and libs on your system.
400 You may need to tweak the \b build/python.prf file to set the correct Python includes and libs on your system.
398
401
399 \subsection Windows
402 \subsection Windows
400
403
401 On Windows, the (non-source) Python Windows installer can be used.
404 On Windows, the (non-source) Python Windows installer can be used.
402 Make sure that you use the same compiler, the current Python distribution is built
405 Make sure that you use the same compiler, the current Python distribution is built
403 with Visual Studio 2003. If you want to use another compiler, you will need to build
406 with Visual Studio 2003. If you want to use another compiler, you will need to build
404 Python yourself, using your compiler.
407 Python yourself, using your compiler.
405
408
406 To build PythonQt, you need to set the environment variable \b PYTHON_PATH to point to the root
409 To build PythonQt, you need to set the environment variable \b PYTHON_PATH to point to the root
407 dir of the python installation and \b PYTHON_LIB to point to
410 dir of the python installation and \b PYTHON_LIB to point to
408 the directory where the python lib file is located.
411 the directory where the python lib file is located.
409
412
410 When using the prebuild Python installer, this will be:
413 When using the prebuild Python installer, this will be:
411
414
412 \code
415 \code
413 > set PYTHON_PATH = c:\Python25
416 > set PYTHON_PATH = c:\Python25
414 > set PYTHON_LIB = c:\Python25\libs
417 > set PYTHON_LIB = c:\Python25\libs
415 \endcode
418 \endcode
416
419
417 When using the python sources, this will be something like:
420 When using the python sources, this will be something like:
418
421
419 \code
422 \code
420 > set PYTHON_PATH = c:\yourDir\Python-2.5.1\
423 > set PYTHON_PATH = c:\yourDir\Python-2.5.1\
421 > set PYTHON_LIB = c:\yourDir\Python-2.5.1\PCbuild8\Win32
424 > set PYTHON_LIB = c:\yourDir\Python-2.5.1\PCbuild8\Win32
422 \endcode
425 \endcode
423
426
424 To build all, do the following (after setting the above variables):
427 To build all, do the following (after setting the above variables):
425
428
426 \code
429 \code
427 > cd PythonQtRoot
430 > cd PythonQtRoot
428 > vcvars32
431 > vcvars32
429 > qmake
432 > qmake
430 > nmake
433 > nmake
431 \endcode
434 \endcode
432
435
433 This should build everything. If Python can not be linked or include files can not be found,
436 This should build everything. If Python can not be linked or include files can not be found,
434 you probably need to tweak \b build/python.prf
437 you probably need to tweak \b build/python.prf
435
438
436 The tests and examples are located in PythonQt/lib.
439 The tests and examples are located in PythonQt/lib.
437
440
438 \subsection Linux
441 \subsection Linux
439
442
440 On Linux, you need to install a Python-dev package.
443 On Linux, you need to install a Python-dev package.
441 If Python can not be linked or include files can not be found,
444 If Python can not be linked or include files can not be found,
442 you probably need to tweak \b build/python.prf
445 you probably need to tweak \b build/python.prf
443
446
444 To build PythonQt, just do a:
447 To build PythonQt, just do a:
445
448
446 \code
449 \code
447 > cd PythonQtRoot
450 > cd PythonQtRoot
448 > qmake
451 > qmake
449 > make all
452 > make all
450 \endcode
453 \endcode
451
454
452 The tests and examples are located in PythonQt/lib.
455 The tests and examples are located in PythonQt/lib.
453 You should add PythonQt/lib to your LD_LIBRARY_PATH so that the runtime
456 You should add PythonQt/lib to your LD_LIBRARY_PATH so that the runtime
454 linker can find the *.so files.
457 linker can find the *.so files.
455
458
456 \subsection MacOsX
459 \subsection MacOsX
457
460
458 On Mac, Python is installed as a Framework, so you should not need to install it.
461 On Mac, Python is installed as a Framework, so you should not need to install it.
459 To build PythonQt, just do a:
462 To build PythonQt, just do a:
460
463
461 \code
464 \code
462 > cd PythonQtRoot
465 > cd PythonQtRoot
463 > qmake
466 > qmake
464 > make all
467 > make all
465 \endcode
468 \endcode
466
469
467 \section Tests
470 \section Tests
468
471
469 There is a unit test that tests most features of PythonQt, see the \b tests subdirectory for details.
472 There is a unit test that tests most features of PythonQt, see the \b tests subdirectory for details.
470
473
471 \section Examples
474 \section Examples
472
475
473 Examples are available in the \b examples directory. The PyScriptingConsole implements a simple
476 Examples are available in the \b examples directory. The PyScriptingConsole implements a simple
474 interactive scripting console that shows how to script a simple application.
477 interactive scripting console that shows how to script a simple application.
475
478
476 The following shows how to integrate PythonQt into you Qt application:
479 The following shows how to integrate PythonQt into you Qt application:
477
480
478 \code
481 \code
479 #include "PythonQt.h"
482 #include "PythonQt.h"
480 #include <QApplication>
483 #include <QApplication>
481 ...
484 ...
482
485
483 int main( int argc, char **argv )
486 int main( int argc, char **argv )
484 {
487 {
485
488
486 QApplication qapp(argc, argv);
489 QApplication qapp(argc, argv);
487
490
488 // init PythonQt and Python itself
491 // init PythonQt and Python itself
489 PythonQt::init(PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut);
492 PythonQt::init(PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut);
490
493
491
494
492 // get a smart pointer to the __main__ module of the Python interpreter
495 // get a smart pointer to the __main__ module of the Python interpreter
493 PythonQtObjectPtr mainContext = PythonQt::self()->getMainModule();
496 PythonQtObjectPtr mainContext = PythonQt::self()->getMainModule();
494
497
495 // add a QObject as variable of name "example" to the namespace of the __main__ module
498 // add a QObject as variable of name "example" to the namespace of the __main__ module
496 PyExampleObject example;
499 PyExampleObject example;
497 PythonQt::self()->addObject(mainContext, "example", &example);
500 PythonQt::self()->addObject(mainContext, "example", &example);
498
501
499 // do something
502 // do something
500 PythonQt::self()->runScript(mainContext, "print example\n");
503 PythonQt::self()->runScript(mainContext, "print example\n");
501 PythonQt::self()->runScript(mainContext, "def multiply(a,b):\n return a*b;\n");
504 PythonQt::self()->runScript(mainContext, "def multiply(a,b):\n return a*b;\n");
502 QVariantList args;
505 QVariantList args;
503 args << 42 << 47;
506 args << 42 << 47;
504 QVariant result = PythonQt::self()->call(mainContext,"multiply", args);
507 QVariant result = PythonQt::self()->call(mainContext,"multiply", args);
505 ...
508 ...
506 \endcode
509 \endcode
507
510
508
511
509 */
512 */
General Comments 0
You need to be logged in to leave comments. Login now