MCPcopy Create free account
hub / github.com/FreeCAD/FreeCAD / addQObject

Method addQObject

src/Gui/PythonWrapper.cpp:411–449  ·  view source on GitHub ↗

! * \brief addQObject * \param obj * \param pyobj * Connects destruction event of a QObject with invalidation of its PythonWrapper via a helper * QObject. */

Source from the content-addressed store, hash-verified

409 * QObject.
410 */
411 void addQObject(QObject* obj, PyObject* pyobj)
412 {
413 // static array to contain created connections so they can be safely disconnected later
414 static std::map<QObject*, QMetaObject::Connection> connections = {};
415
416 const auto PyW_uniqueName = QString::number(reinterpret_cast<quintptr>(pyobj));
417 auto PyW_invalidator = findChild<QObject*>(PyW_uniqueName, Qt::FindDirectChildrenOnly);
418
419 if (!PyW_invalidator) {
420 PyW_invalidator = new QObject(this);
421 PyW_invalidator->setObjectName(PyW_uniqueName);
422
423 Py_INCREF(pyobj);
424 }
425 else if (connections.contains(PyW_invalidator)) {
426 disconnect(connections[PyW_invalidator]);
427 connections.erase(PyW_invalidator);
428 }
429
430 auto destroyedFun = [pyobj]() {
431 Base::PyGILStateLocker lock;
432
433 if (auto sbkPtr = reinterpret_cast<SbkObject*>(pyobj); sbkPtr) {
434 Shiboken::Object::setValidCpp(sbkPtr, false);
435 }
436 else {
437 Base::Console().developerError(
438 "WrapperManager",
439 "A QObject has just been destroyed after its Pythonic wrapper.\n"
440 );
441 }
442
443 Py_DECREF(pyobj);
444 };
445
446 connections[PyW_invalidator]
447 = connect(PyW_invalidator, &QObject::destroyed, this, destroyedFun);
448 connect(obj, &QObject::destroyed, PyW_invalidator, &QObject::deleteLater);
449 }
450
451private:
452 void wrapQApplication()

Callers 3

fromQActionMethod · 0.80
fromQObjectMethod · 0.80
fromQWidgetMethod · 0.80

Calls 5

setObjectNameMethod · 0.80
developerErrorMethod · 0.80
connectFunction · 0.70
containsMethod · 0.45
eraseMethod · 0.45

Tested by

no test coverage detected