PythonQt
PythonQtObjectPtr.h
Go to the documentation of this file.
1 #ifndef _PYTHONQTOBJECTPTR_H
2 #define _PYTHONQTOBJECTPTR_H
3 
4 /*
5  *
6  * Copyright (C) 2010 MeVis Medical Solutions AG All Rights Reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * Further, this software is distributed without any warranty that it is
19  * free of the rightful claim of any third person regarding infringement
20  * or the like. Any license provided herein, whether implied or
21  * otherwise, applies only to this software file. Patent licenses, if
22  * any, provided herein do not apply to combinations of this program with
23  * other software, or any other product whatsoever.
24  *
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
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28  *
29  * Contact information: MeVis Medical Solutions AG, Universitaetsallee 29,
30  * 28359 Bremen, Germany or:
31  *
32  * http://www.mevis.de
33  *
34  */
35 
36 //----------------------------------------------------------------------------------
43 //----------------------------------------------------------------------------------
44 
45 #include "PythonQtPythonInclude.h"
46 
47 #include "PythonQtSystem.h"
48 #include "PythonQtThreadSupport.h"
49 #include <QVariant>
50 #include <QVariantList>
51 #include <QVariantMap>
52 
54 
57 {
58 public:
59  PythonQtObjectPtr():_object(nullptr) {}
60 
62  :_object(nullptr) {
63  setObject(p.object());
64  }
65 
68  :_object(p.takeObject()) {
69  }
70 
73 
75  PythonQtObjectPtr(const QVariant& variant):_object(nullptr) {
76  fromVariant(variant);
77  }
78 
80 
82 
84  bool fromVariant(const QVariant& variant);
85 
87  QVariant toVariant();
88 
90  QVariant toLocalVariant();
91 
93  setObject(p.object());
94  return *this;
95  }
96 
99  if (_object) {
100  setObject(nullptr);
101  }
102  _object = p.takeObject();
103  return *this;
104  }
105 
108 
110  setObject(o);
111  return *this;
112  }
113 
114 
115  PythonQtObjectPtr &operator=(const QVariant& variant) {
116  fromVariant(variant);
117  return *this;
118  }
119 
120 
121  bool operator==( const PythonQtObjectPtr &p ) const {
122  return object() == p.object();
123  }
124 
125  bool operator!= ( const PythonQtObjectPtr& p ) const {
126  return !( *this == p );
127  }
128 
129  bool operator==( PyObject* p ) const {
130  return object() == p;
131  }
132 
133  bool operator!= ( PyObject* p ) const {
134  return object() != p;
135  }
136 
137  bool isNull() const { return !object(); }
138 
139  PyObject* operator->() const { return object(); }
140 
141  PyObject& operator*() const { return *( object() ); }
142 
143  operator PyObject*() const { return object(); }
144 
146  void setNewRef(PyObject* o);
147 
148  PyObject* object() const {
149  return _object;
150  }
151 
153  QVariant evalScript(const QString& script, int start = Py_file_input);
154 
157  QVariant evalCode(PyObject* pycode);
158 
160  void evalFile(const QString& filename);
161 
163  void addObject(const QString& name, QObject* object);
164 
166  void addVariable(const QString& name, const QVariant& v);
167 
169  void removeVariable(const QString& name);
170 
172  QVariant getVariable(const QString& name);
173 
175  QVariant call(const QString& callable, const QVariantList& args = QVariantList(), const QVariantMap& kwargs = QVariantMap());
176 
178  QVariant call(const QVariantList& args = QVariantList(), const QVariantMap& kwargs = QVariantMap());
179 
183  PyObject* o = _object;
184  _object = nullptr;
185  return o;
186  }
187 
188 protected:
189 
190  void setObject(PyObject* o);
191 
192 private:
193  PyObject* _object;
194 };
195 
198 {
199 public:
200  PythonQtSafeObjectPtr() :_object(nullptr) {}
201 
203  :_object(nullptr) {
204  setObject(p.object());
205  }
206 
208  :_object(nullptr) {
209  setObject(p.object());
210  }
211 
214  :_object(p._object) {
215  p._object = nullptr;
216  }
217 
220  :_object(p.takeObject()) {
221  }
222 
224 
226 
228  setObject(p.object());
229  return *this;
230  }
231 
233  setObjectUnsafe(p.object());
234  return *this;
235  }
236 
239  if (_object) {
240  setObject(nullptr);
241  }
242  _object = p._object;
243  p._object = nullptr;
244  return *this;
245  }
246 
249  if (_object) {
250  setObjectUnsafe(nullptr);
251  }
252  _object = p.takeObject();
253  return *this;
254  }
255 
257  setObject(o);
258  return *this;
259  }
260 
261  bool operator==(const PythonQtSafeObjectPtr &p) const {
262  return object() == p.object();
263  }
264 
265  bool operator!= (const PythonQtSafeObjectPtr& p) const {
266  return !(*this == p);
267  }
268 
269  bool operator==(PyObject* p) const {
270  return object() == p;
271  }
272 
273  bool operator!= (PyObject* p) const {
274  return object() != p;
275  }
276 
277  bool isNull() const { return !object(); }
278 
279  PyObject* operator->() const { return object(); }
280 
281  PyObject& operator*() const { return *(object()); }
282 
283  operator PyObject*() const { return object(); }
284 
285  PyObject* object() const {
286  return _object;
287  }
288 
292  PyObject* o = _object;
293  _object = nullptr;
294  return o;
295  }
296 
297 protected:
298  void setObject(PyObject* o);
300 
301 private:
302  PyObject* _object;
303 };
304 
305 // We don't want QVariant to take PythonQtObjectPtr via QVariant::fromValue, because it is unsafe when using multi-threading/GIL
306 // A QVariant can still be obtained with PythonQtObjectPtr::toLocalVariant().
307 //Q_DECLARE_METATYPE(PythonQtObjectPtr)
308 
309 // register PythonQtSafeObjectPtr to the meta type system
310 Q_DECLARE_METATYPE(PythonQtSafeObjectPtr)
311 
312 #endif
313 
struct _object PyObject
#define PYTHONQT_EXPORT
a smart pointer that stores a PyObject pointer and that handles reference counting automatically
PythonQtObjectPtr & operator=(PythonQtObjectPtr &&p) noexcept
rvalue assignment operator that steals the reference from p
QVariant call(const QVariantList &args=QVariantList(), const QVariantMap &kwargs=QVariantMap())
call the contained python object directly, returns the result converted to a QVariant
PyObject * operator->() const
PythonQtObjectPtr(PythonQtObjectPtr &&p) noexcept
rvalue copy constructor, does not need any incref/decref.
void setObject(PyObject *o)
void addVariable(const QString &name, const QVariant &v)
add the given variable to the module
void evalFile(const QString &filename)
evaluates the given code in the context
PythonQtObjectPtr(PyObject *o)
PythonQtObjectPtr(const PythonQtObjectPtr &p)
PythonQtObjectPtr(PythonQtSafeObjectPtr &&p)
rvalue copy constructor, does not need any incref/decref.
QVariant toLocalVariant()
Returns a PythonQtObjectPtr as a QVariant. Only use this when you know that the variant is only used ...
bool operator==(PyObject *p) const
PyObject * object() const
PyObject * takeObject()
PythonQtObjectPtr & operator=(PythonQtSafeObjectPtr &&p)
rvalue assignment operator that steals the reference from p
QVariant evalScript(const QString &script, int start=Py_file_input)
evaluates the given script code in the context of this object and returns the result value
void removeVariable(const QString &name)
remove the given variable
PythonQtObjectPtr(const QVariant &variant)
If the given variant holds a PythonQtObjectPtr, extract the value from it and hold onto the reference...
QVariant toVariant()
Returns a PythonQtSafeObjectPtr as a QVariant. It does not return a PythonQtObjectPtr,...
PythonQtObjectPtr & operator=(const QVariant &variant)
PythonQtObjectPtr & operator=(const PythonQtObjectPtr &p)
void addObject(const QString &name, QObject *object)
add the given object to the module as a variable with name (it can be removed via clearVariable)
PyObject & operator*() const
bool fromVariant(const QVariant &variant)
If the given variant holds a PythonQtObjectPtr, extract the value from it and hold onto the reference...
QVariant getVariable(const QString &name)
get the variable with the name of the module, returns an invalid QVariant on error
QVariant call(const QString &callable, const QVariantList &args=QVariantList(), const QVariantMap &kwargs=QVariantMap())
call the given python object (in the scope of the current object), returns the result converted to a ...
bool operator==(const PythonQtObjectPtr &p) const
QVariant evalCode(PyObject *pycode)
void setNewRef(PyObject *o)
sets the object and passes the ownership (stealing the reference, in Python slang)
PythonQtObjectPtr & operator=(PyObject *o)
a smart pointer that stores a PyObject pointer and that handles reference counting automatically
void setObject(PyObject *o)
PythonQtSafeObjectPtr & operator=(PyObject *o)
void setObjectUnsafe(PyObject *o)
PythonQtSafeObjectPtr(PythonQtSafeObjectPtr &&p) noexcept
rvalue copy constructor, does not need any incref/decref.
PythonQtSafeObjectPtr(const PythonQtSafeObjectPtr &p)
PyObject & operator*() const
PythonQtSafeObjectPtr & operator=(const PythonQtSafeObjectPtr &p)
PythonQtSafeObjectPtr(PyObject *o)
PythonQtSafeObjectPtr(PythonQtObjectPtr &&p)
rvalue copy constructor, does not need any incref/decref.
PythonQtSafeObjectPtr & operator=(const PythonQtObjectPtr &p)
PyObject * operator->() const
PythonQtSafeObjectPtr & operator=(PythonQtSafeObjectPtr &&p) noexcept
rvalue assignment operator that steals the reference from p
PyObject * object() const
bool operator==(PyObject *p) const
PythonQtSafeObjectPtr(const PythonQtObjectPtr &p)
PythonQtSafeObjectPtr & operator=(PythonQtObjectPtr &&p)
rvalue assignment operator that steals the reference from p
bool operator==(const PythonQtSafeObjectPtr &p) const