itom  3.0.0
pythonQtSignalMapper.h
1 /* ********************************************************************
2  itom software
3  URL: http://www.uni-stuttgart.de/ito
4  Copyright (C) 2016, Institut fuer Technische Optik (ITO),
5  Universitaet Stuttgart, Germany
6 
7  This file is part of itom.
8 
9  itom is free software; you can redistribute it and/or modify it
10  under the terms of the GNU Library General Public Licence as published by
11  the Free Software Foundation; either version 2 of the Licence, or (at
12  your option) any later version.
13 
14  itom is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
17  General Public Licence for more details.
18 
19  You should have received a copy of the GNU Library General Public License
20  along with itom. If not, see <http://www.gnu.org/licenses/>.
21 *********************************************************************** */
22 
23 #ifndef PYTHONQTSIGNALMAPPER_H
24 #define PYTHONQTSIGNALMAPPER_H
25 
26 #ifndef Q_MOC_RUN
27  #define PY_ARRAY_UNIQUE_SYMBOL itom_ARRAY_API
28 
29  //python
30  // see http://vtk.org/gitweb?p=VTK.git;a=commitdiff;h=7f3f750596a105d48ea84ebfe1b1c4ca03e0bab3
31  #if (defined _DEBUG) && (defined WIN32)
32  #undef _DEBUG
33  #include "Python.h"
34  #define _DEBUG
35  #else
36  #include "Python.h"
37  #endif
38 #endif
39 
40 #include "../global.h"
41 
42 #include <qvariant.h>
43 #include <qobject.h>
44 
45 namespace ito
46 {
47 
49 {
50 public:
51 
54  m_slotId(-1),
55  m_signalId(-1),
56  m_function(NULL),
57  m_boundedInstance(NULL),
58  m_boundedMethod(false)
59 
60  {
61  };
62 
64 
76  PythonQtSignalTarget(IntList &argTypeList, int slotId, int signalId, PyObject* callable, const char *signal) :
77  m_slotId(slotId),
78  m_signalId(signalId),
79  m_function(NULL),
80  m_boundedInstance(NULL),
81  m_boundedMethod(false),
82  m_signalName(signal)
83  {
85  PyObject *temp = NULL;
86 
87  if(PyMethod_Check(callable))
88  {
89  m_boundedMethod = true;
90  Py_XDECREF(m_boundedInstance);
91  Py_XDECREF(m_function);
92  temp = PyMethod_Self(callable); //borrowed
93  m_boundedInstance = PyWeakref_NewRef(temp, NULL); //new ref (weak reference used to avoid cyclic garbage collection)
94  temp = PyMethod_Function(callable); //borrowed
95  m_function = PyWeakref_NewRef(temp, NULL); //new ref
96  }
97  else if(PyFunction_Check(callable))
98  {
99  m_boundedMethod = false;
100  Py_XDECREF(m_boundedInstance);
101  Py_XDECREF(m_function);
102  m_function = PyWeakref_NewRef(callable, NULL); //new ref
103  }
104  };
105 
108  m_slotId(-1),
109  m_signalId(-1),
110  m_function(NULL),
111  m_boundedInstance(NULL),
112  m_boundedMethod(false),
114  {
115  Py_XDECREF(m_boundedInstance);
116  Py_XDECREF(m_function);
117  m_slotId = copy.slotId();
118  m_signalId = copy.signalId();
119  m_argTypeList = copy.argTypeList();
120 
122  m_function = copy.m_function;
123  Py_XINCREF(m_function);
125  Py_XINCREF(m_boundedInstance);
126  }
127 
130  {
131  Py_XDECREF(m_boundedInstance);
132  Py_XDECREF(m_function);
133  m_argTypeList.clear();
134  }
135 
137  inline int signalId() const { return m_signalId; }
138 
140  inline int slotId() const { return m_slotId; }
141 
142  // call the python callable with the given arguments (docs see source file)
143  void call(void ** arguments) const;
144 
146  inline IntList argTypeList() const { return m_argTypeList; };
147 
149 
156  bool isSame(int signalId, PyObject* callable) const
157  {
158  if(signalId == m_signalId)
159  {
160  if(PyMethod_Check(callable))
161  {
162  return PyMethod_Self(callable) == PyWeakref_GetObject(m_boundedInstance) && PyMethod_Function(callable) == PyWeakref_GetObject(m_function);
163  }
164  return callable == PyWeakref_GetObject(m_function);
165  }
166  return false;
167  }
168 
169 private:
170  int m_slotId;
172  IntList m_argTypeList;
173  PyObject *m_function;
174  PyObject *m_boundedInstance;
176  QString m_signalName;
177 };
178 
195 class PythonQtSignalMapperBase : public QObject
196 {
197  Q_OBJECT
198 public:
200 };
201 
202 
204 {
205 
206 public:
207  PythonQtSignalMapper(unsigned int initSlotCount);
209 
210  bool addSignalHandler(QObject *obj, const char* signal, int sigId, PyObject* callable, IntList &argTypeList);
211  bool removeSignalHandler(QObject *obj, const char* signal, int sigId, PyObject* callable);
212  void removeSignalHandlers();
213  virtual int qt_metacall(QMetaObject::Call c, int id, void **arguments);
214 
215 private:
216  QList<PythonQtSignalTarget> m_targets;
218 };
219 
220 } //end namespace ito
221 
222 #endif
IntList m_argTypeList
type id&#39;s from QMetaType::type("..."), describing the arguments of the function-call ...
Definition: pythonQtSignalMapper.h:172
int signalId() const
gets the id of the original signal
Definition: pythonQtSignalMapper.h:137
Definition: pythonQtSignalMapper.h:48
PyObject * m_function
weak reference to the python-function, that acts as slot
Definition: pythonQtSignalMapper.h:173
PythonQtSignalTarget(const PythonQtSignalTarget &copy)
copy constructor
Definition: pythonQtSignalMapper.h:107
PythonQtSignalTarget(IntList &argTypeList, int slotId, int signalId, PyObject *callable, const char *signal)
constructor
Definition: pythonQtSignalMapper.h:76
void call(void **arguments) const
invokes the python method or function
Definition: pythonQtSignalMapper.cpp:198
bool isSame(int signalId, PyObject *callable) const
Compares this signal target with given values.
Definition: pythonQtSignalMapper.h:156
Definition: apiFunctionsGraph.cpp:39
~PythonQtSignalTarget()
destructor
Definition: pythonQtSignalMapper.h:129
bool m_boundedMethod
true if the python function is bounded (non-static member of a class), else false ...
Definition: pythonQtSignalMapper.h:175
IntList argTypeList() const
returns list of type-numbers of arguments
Definition: pythonQtSignalMapper.h:146
int slotId() const
gets the id that was assigned to this simulated slot
Definition: pythonQtSignalMapper.h:140
int m_slotCount
index of the last virtual slot managed by this instance (auto-incremented)
Definition: pythonQtSignalMapper.h:217
int m_slotId
index of this slot
Definition: pythonQtSignalMapper.h:170
PythonQtSignalTarget()
empty constructor
Definition: pythonQtSignalMapper.h:53
int m_signalId
index of the connected signal
Definition: pythonQtSignalMapper.h:171
PyObject * m_boundedInstance
weak reference to the python-class instance of the function (if the function is bounded) or NULL if t...
Definition: pythonQtSignalMapper.h:174
QString m_signalName
signature of the signal (mainly used for debugging reasons)
Definition: pythonQtSignalMapper.h:176
base class for PythonQtSignalMapper
Definition: pythonQtSignalMapper.h:195
This class provides the possibility to redirect any signal emitted in an user-defined GUI to differen...
Definition: pythonQtSignalMapper.h:203
QList< PythonQtSignalTarget > m_targets
list with all virtual slot targets that are the destination for any registered signal-slot-connection...
Definition: pythonQtSignalMapper.h:216