signalmanager.h 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright (C) 2016 The Qt Company Ltd.
  2. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
  3. #ifndef SIGNALMANAGER_H
  4. #define SIGNALMANAGER_H
  5. #include "pysidemacros.h"
  6. #include <sbkpython.h>
  7. #include <shibokenmacros.h>
  8. #include <QtCore/qmetaobject.h>
  9. #include <optional>
  10. QT_FORWARD_DECLARE_CLASS(QDataStream)
  11. QT_FORWARD_DECLARE_CLASS(QDebug)
  12. namespace PySide
  13. {
  14. /// Thin wrapper for PyObject which increases the reference count at the constructor but *NOT* at destructor.
  15. class PYSIDE_API PyObjectWrapper
  16. {
  17. public:
  18. PyObjectWrapper();
  19. explicit PyObjectWrapper(PyObject* me);
  20. PyObjectWrapper(const PyObjectWrapper &other);
  21. PyObjectWrapper& operator=(const PyObjectWrapper &other);
  22. PyObjectWrapper(PyObjectWrapper&&) noexcept;
  23. PyObjectWrapper &operator=(PyObjectWrapper &&) noexcept;
  24. void reset(PyObject *o);
  25. ~PyObjectWrapper();
  26. operator PyObject*() const;
  27. // FIXME: To be removed in Qt7
  28. // This was done to make QAbstractItemModel::data() work without explicit conversion of
  29. // QVariant(PyObjectWrapper) to QVariant(int). This works because QAbstractItemModel::data()
  30. // inturn calls legacyEnumValueFromModelData(const QVariant &data). But this function will
  31. // be removed in Qt7.
  32. // The proper fix would be to associate PyObjectWrapper to the corresponding C++ Enum.
  33. int toInt() const;
  34. static int metaTypeId();
  35. private:
  36. PyObject* m_me;
  37. };
  38. PYSIDE_API QDataStream &operator<<(QDataStream& out, const PyObjectWrapper& myObj);
  39. PYSIDE_API QDataStream &operator>>(QDataStream& in, PyObjectWrapper& myObj);
  40. PYSIDE_API QDebug operator<<(QDebug debug, const PyObjectWrapper &myObj);
  41. class PYSIDE_API SignalManager
  42. {
  43. public:
  44. Q_DISABLE_COPY_MOVE(SignalManager)
  45. ~SignalManager() = default;
  46. using QmlMetaCallErrorHandler = std::optional<int>(*)(QObject *object);
  47. static void init();
  48. static void setQmlMetaCallErrorHandler(QmlMetaCallErrorHandler handler);
  49. static bool emitSignal(QObject* source, const char* signal, PyObject* args);
  50. static int qt_metacall(QObject* object, QMetaObject::Call call, int id, void** args);
  51. // Used to register a new signal/slot on QMetaobject of source.
  52. static bool registerMetaMethod(QObject* source, const char* signature,
  53. QMetaMethod::MethodType type);
  54. static int registerMetaMethodGetIndex(QObject* source, const char *signature,
  55. QMetaMethod::MethodType type);
  56. static int registerMetaMethodGetIndexBA(QObject* source, const QByteArray &signature,
  57. QMetaMethod::MethodType type);
  58. // used to discovery metaobject
  59. static const QMetaObject* retrieveMetaObject(PyObject* self);
  60. // Utility function to call a python method using args received in qt_metacall
  61. static int callPythonMetaMethod(QMetaMethod method, void **args, PyObject *callable);
  62. static int callPythonMetaMethod(const QByteArrayList &parameterTypes,
  63. const char *returnType /* = nullptr */,
  64. void **args, PyObject *callable);
  65. static void handleMetaCallError();
  66. };
  67. }
  68. Q_DECLARE_METATYPE(PySide::PyObjectWrapper)
  69. #endif