|
34 | 34 | /*! |
35 | 35 | // \file PythonQt.cpp |
36 | 36 | // \author Florian Link |
37 | | -// \author Last changed by $Author: florian $ |
38 | 37 | // \date 2006-05 |
39 | 38 | */ |
40 | 39 | //---------------------------------------------------------------------------------- |
@@ -324,8 +323,7 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName) |
324 | 323 | void PythonQt::cleanup() |
325 | 324 | { |
326 | 325 | if (_self) { |
327 | | - // Remove signal handlers in advance, since destroying them calls back into |
328 | | - // PythonQt::priv()->removeSignalEmitter() |
| 326 | + // Remove all created signal receivers |
329 | 327 | _self->removeSignalHandlers(); |
330 | 328 |
|
331 | 329 | delete _self; |
@@ -879,65 +877,36 @@ PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, Py |
879 | 877 | return result; |
880 | 878 | } |
881 | 879 |
|
882 | | -PythonQtSignalReceiver* PythonQt::getSignalReceiver(QObject* obj) |
883 | | -{ |
884 | | - PythonQtSignalReceiver* r = _p->_signalReceivers[obj]; |
885 | | - if (!r) { |
886 | | - r = new PythonQtSignalReceiver(obj); |
887 | | - _p->_signalReceivers.insert(obj, r); |
888 | | - } |
889 | | - return r; |
890 | | -} |
891 | | - |
892 | 880 | bool PythonQt::addSignalHandler(QObject* obj, const char* signal, PyObject* module, const QString& objectname) |
893 | 881 | { |
894 | | - bool flag = false; |
895 | 882 | PythonQtObjectPtr callable = lookupCallable(module, objectname); |
896 | 883 | if (callable) { |
897 | | - PythonQtSignalReceiver* r = getSignalReceiver(obj); |
898 | | - flag = r->addSignalHandler(signal, callable); |
899 | | - if (!flag) { |
900 | | - // signal not found |
901 | | - } |
| 884 | + return _p->addSignalHandler(obj, signal, callable); |
902 | 885 | } else { |
903 | 886 | // callable not found |
904 | 887 | } |
905 | | - return flag; |
| 888 | + return false; |
906 | 889 | } |
907 | 890 |
|
908 | | -bool PythonQt::addSignalHandler(QObject* obj, const char* signal, PyObject* receiver) |
| 891 | +bool PythonQt::addSignalHandler(QObject* obj, const char* signal, PyObject* callable) |
909 | 892 | { |
910 | | - bool flag = false; |
911 | | - PythonQtSignalReceiver* r = getSignalReceiver(obj); |
912 | | - if (r) { |
913 | | - flag = r->addSignalHandler(signal, receiver); |
914 | | - } |
915 | | - return flag; |
| 893 | + return _p->addSignalHandler(obj, signal, callable); |
916 | 894 | } |
917 | 895 |
|
918 | 896 | bool PythonQt::removeSignalHandler(QObject* obj, const char* signal, PyObject* module, const QString& objectname) |
919 | 897 | { |
920 | | - bool flag = false; |
921 | 898 | PythonQtObjectPtr callable = lookupCallable(module, objectname); |
922 | 899 | if (callable) { |
923 | | - PythonQtSignalReceiver* r = _p->_signalReceivers[obj]; |
924 | | - if (r) { |
925 | | - flag = r->removeSignalHandler(signal, callable); |
926 | | - } |
| 900 | + return _p->removeSignalHandler(obj, signal, callable); |
927 | 901 | } else { |
928 | 902 | // callable not found |
929 | 903 | } |
930 | | - return flag; |
| 904 | + return false; |
931 | 905 | } |
932 | 906 |
|
933 | | -bool PythonQt::removeSignalHandler(QObject* obj, const char* signal, PyObject* receiver) |
| 907 | +bool PythonQt::removeSignalHandler(QObject* obj, const char* signal, PyObject* callable) |
934 | 908 | { |
935 | | - bool flag = false; |
936 | | - PythonQtSignalReceiver* r = _p->_signalReceivers[obj]; |
937 | | - if (r) { |
938 | | - flag = r->removeSignalHandler(signal, receiver); |
939 | | - } |
940 | | - return flag; |
| 909 | + return _p->removeSignalHandler(obj, signal, callable); |
941 | 910 | } |
942 | 911 |
|
943 | 912 | PythonQtObjectPtr PythonQt::lookupCallable(PyObject* module, const QString& name) |
@@ -1619,20 +1588,14 @@ void PythonQtPrivate::registerQObjectClassNames(const QStringList& names) |
1619 | 1588 | } |
1620 | 1589 | } |
1621 | 1590 |
|
1622 | | -void PythonQtPrivate::removeSignalEmitter(QObject* obj) |
1623 | | -{ |
1624 | | - _signalReceivers.remove(obj); |
1625 | | -} |
1626 | | - |
1627 | 1591 | void PythonQt::removeSignalHandlers() |
1628 | 1592 | { |
1629 | | - QList<PythonQtSignalReceiver*> signalReceivers = _p->_signalReceivers.values(); |
1630 | | - |
1631 | | - // just delete all signal receivers, they will remove themselves via removeSignalEmitter() |
1632 | | - for (PythonQtSignalReceiver* receiver : qAsConst(signalReceivers)) { |
1633 | | - delete receiver; |
| 1593 | + auto it = _p->_signalReceivers.begin(); |
| 1594 | + while (it != _p->_signalReceivers.end()) { |
| 1595 | + it.value()->markAsRemoved(); |
| 1596 | + delete it.value(); |
| 1597 | + it++; |
1634 | 1598 | } |
1635 | | - // just to be sure, clear the receiver map as well |
1636 | 1599 | _p->_signalReceivers.clear(); |
1637 | 1600 | } |
1638 | 1601 |
|
@@ -2012,6 +1975,57 @@ PythonQtClassInfo* PythonQtPrivate::lookupClassInfoAndCreateIfNotPresent(const c |
2012 | 1975 | return info; |
2013 | 1976 | } |
2014 | 1977 |
|
| 1978 | +bool PythonQtPrivate::addSignalHandler(QObject* sender, const char* signal, PyObject* callable) |
| 1979 | +{ |
| 1980 | + // Note: It is assumed that the GIL is held when this is called |
| 1981 | + bool ok = false; |
| 1982 | + int sigId = PythonQtSignalReceiver::getSignalIndex(sender, signal); |
| 1983 | + if (sigId >= 0) { |
| 1984 | + // create PythonQtMethodInfo from signal |
| 1985 | + auto* receiver = new PythonQtSignalReceiver(sender, sigId, callable); |
| 1986 | + _signalReceivers.insert(SignalKey(sender, sigId), receiver); |
| 1987 | + ok = true; |
| 1988 | + } |
| 1989 | + return ok; |
| 1990 | +} |
| 1991 | + |
| 1992 | +bool PythonQtPrivate::removeSignalHandler(QObject* sender, const char* signal, PyObject* callable) |
| 1993 | +{ |
| 1994 | + // Note: It is assumed that the GIL is held when this is called |
| 1995 | + int foundCount = 0; |
| 1996 | + int sigId = PythonQtSignalReceiver::getSignalIndex(sender, signal); |
| 1997 | + if (sigId >= 0) { |
| 1998 | + SignalKey hashKey(sender, sigId); |
| 1999 | + auto it = _signalReceivers.find(hashKey); |
| 2000 | + while (it != _signalReceivers.end() && it.key() == hashKey) { |
| 2001 | + if (!callable || it.value()->isSameCallable(callable)) { |
| 2002 | + it.value()->markAsRemoved(); |
| 2003 | + // delete later in case the connection is removed from the receiver callable itself |
| 2004 | + it.value()->deleteLater(); |
| 2005 | + foundCount++; |
| 2006 | + it = _signalReceivers.erase(it); |
| 2007 | + } else { |
| 2008 | + it++; |
| 2009 | + } |
| 2010 | + } |
| 2011 | + } |
| 2012 | + return foundCount > 0; |
| 2013 | +} |
| 2014 | + |
| 2015 | +void PythonQtPrivate::removeSignalReceiver(PythonQtSignalReceiver* receiver) |
| 2016 | +{ |
| 2017 | + PYTHONQT_GIL_SCOPE |
| 2018 | + SignalKey hashKey(receiver->sender(), receiver->signalId()); |
| 2019 | + auto it = _signalReceivers.find(hashKey); |
| 2020 | + while (it != _signalReceivers.end() && it.key() == hashKey) { |
| 2021 | + if (it.value() == receiver) { |
| 2022 | + _signalReceivers.erase(it); |
| 2023 | + break; // each receiver is only entered once |
| 2024 | + } |
| 2025 | + it++; |
| 2026 | + } |
| 2027 | +} |
| 2028 | + |
2015 | 2029 | void PythonQt::addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb) |
2016 | 2030 | { |
2017 | 2031 | _p->addPolymorphicHandler(typeName, cb); |
|
0 commit comments