diff options
author | renatofilho <renato.filho@openbossa.org> | 2010-10-28 16:28:43 -0300 |
---|---|---|
committer | renatofilho <renato.filho@openbossa.org> | 2010-10-28 17:40:12 -0300 |
commit | bd8239b1cd99d25c26eb99a051072254342ab0bb (patch) | |
tree | 12fce76bd9206473ead1600e05d5591619f98393 | |
parent | a1524b78b632d99aa6076391d0d77e46271dd7c8 (diff) | |
download | pyside-bd8239b1cd99d25c26eb99a051072254342ab0bb.tar.gz pyside-bd8239b1cd99d25c26eb99a051072254342ab0bb.tar.xz pyside-bd8239b1cd99d25c26eb99a051072254342ab0bb.zip |
Stop signal/slot connection if is impossible to register that on object.
Created unit test for bug #442, #437.
Fixes bug #442.
Reviewer: Marcelo Lira <marcelo.lira@openbossa.org>
Luciano Wolf <luciano.wolf@openbossa.org>
-rw-r--r-- | PySide/QtCore/glue/qobject_connect.cpp | 10 | ||||
-rw-r--r-- | libpyside/qsignal.cpp | 13 | ||||
-rw-r--r-- | libpyside/signalmanager.cpp | 2 | ||||
-rw-r--r-- | tests/QtDeclarative/CMakeLists.txt | 1 | ||||
-rwxr-xr-x | tests/QtDeclarative/connect_python_qml.py | 30 | ||||
-rw-r--r-- | tests/QtDeclarative/connect_python_qml.qml | 20 |
6 files changed, 66 insertions, 10 deletions
diff --git a/PySide/QtCore/glue/qobject_connect.cpp b/PySide/QtCore/glue/qobject_connect.cpp index cf78779..b98a411 100644 --- a/PySide/QtCore/glue/qobject_connect.cpp +++ b/PySide/QtCore/glue/qobject_connect.cpp @@ -32,7 +32,8 @@ static bool qobjectConnect(QObject* source, const char* signal, QObject* receive return false; signal++; - PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal); + if (!PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal)) + return false; bool isSignal = PySide::isSignal(slot); slot++; @@ -46,7 +47,9 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject return false; signal++; - PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal); + if (!PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal)) + return false; + int signalIndex = source->metaObject()->indexOfMethod(signal); PySide::SignalManager& signalManager = PySide::SignalManager::instance(); @@ -70,7 +73,8 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject if (usingGlobalReceiver) { signalManager.addGlobalSlot(slot, callback); } else { - PySide::SignalManager::registerMetaMethod(receiver, slot, QMetaMethod::Slot); + if (!PySide::SignalManager::registerMetaMethod(receiver, slot, QMetaMethod::Slot)) + return false; } slotIndex = metaObject->indexOfSlot(slot); } diff --git a/libpyside/qsignal.cpp b/libpyside/qsignal.cpp index 23ee7ff..31d30fc 100644 --- a/libpyside/qsignal.cpp +++ b/libpyside/qsignal.cpp @@ -523,6 +523,8 @@ char* getTypeName(PyObject* type) return typeName; } else if (PyString_Check(type)) { return strdup(PyString_AS_STRING(type)); + } else if (type == Py_None) { + return strdup("void"); } return 0; } @@ -537,7 +539,7 @@ char* signalBuildSignature(const char *name, const char *signature) char* signalParseSignature(PyObject *args) { char *signature = 0; - if (args && (PyString_Check(args) || (!PySequence_Check(args) && (args != Py_None)))) + if (args && (PyString_Check(args) || !PySequence_Check(args))) return getTypeName(args); for(Py_ssize_t i = 0, i_max = PySequence_Size(args); i < i_max; i++) { @@ -623,12 +625,11 @@ PyObject* signalNewFromMethod(PyObject* source, const QList<QMetaMethod>& method item->d = new PySideSignalInstanceDataPrivate; PySideSignalInstanceDataPrivate* selfPvt = item->d; selfPvt->source = source; - const char* cppSignature = m.signature(); + QByteArray cppName(m.signature()); + cppName = cppName.mid(0, cppName.indexOf('(')); // separe SignalName - selfPvt->signalName = strdup(cppSignature); - char* endName = strchr(selfPvt->signalName, '('); - endName = '\0'; - selfPvt->signature = strdup(cppSignature); + selfPvt->signalName = strdup(cppName.data()); + selfPvt->signature = strdup(m.signature()); selfPvt->homonymousMethod = 0; selfPvt->next = 0; } diff --git a/libpyside/signalmanager.cpp b/libpyside/signalmanager.cpp index 69c4492..53f6a45 100644 --- a/libpyside/signalmanager.cpp +++ b/libpyside/signalmanager.cpp @@ -482,7 +482,7 @@ bool SignalManager::registerMetaMethod(QObject* source, const char* signature, Q if (methodIndex == -1) { Shiboken::SbkBaseWrapper* self = (Shiboken::SbkBaseWrapper*) Shiboken::BindingManager::instance().retrieveWrapper(source); if (!self->containsCppWrapper) { - qWarning() << "You can't add dynamic signals or slots on an object originated from C++."; + qWarning() << "Invalid Signal signature:" << signature; return false; } else { PySide::DynamicQMetaObject* dynMetaObj = reinterpret_cast<PySide::DynamicQMetaObject*>(const_cast<QMetaObject*>(metaObject)); diff --git a/tests/QtDeclarative/CMakeLists.txt b/tests/QtDeclarative/CMakeLists.txt index 4896010..98b797c 100644 --- a/tests/QtDeclarative/CMakeLists.txt +++ b/tests/QtDeclarative/CMakeLists.txt @@ -1,2 +1,3 @@ PYSIDE_TEST(qdeclarativenetwork_test.py FALSE) PYSIDE_TEST(qdeclarativeview_test.py FALSE) +PYSIDE_TEST(connect_python_qml.py FALSE) diff --git a/tests/QtDeclarative/connect_python_qml.py b/tests/QtDeclarative/connect_python_qml.py new file mode 100755 index 0000000..bb50515 --- /dev/null +++ b/tests/QtDeclarative/connect_python_qml.py @@ -0,0 +1,30 @@ +'''Test case for bug #442''' + +from PySide import QtCore, QtGui, QtDeclarative +from helper import adjust_filename, TimedQApplication +import unittest + +class TestConnectionWithInvalidSignature(TimedQApplication): + def onButtonClicked(self): + self.buttonClicked = True + self.app.quit() + + def onButtonFailClicked(self): + pass + + def testFailConnection(self): + self.buttonClicked = False + self.buttonFailClicked = False + view = QtDeclarative.QDeclarativeView() + view.setSource(QtCore.QUrl(adjust_filename('connect_python_qml.qml', __file__))) + root = view.rootObject() + button = root.findChild(QtCore.QObject, "buttonMouseArea") + self.assertRaises(TypeError, QtCore.QObject.connect, [button,QtCore.SIGNAL('clicked()'), self.onButtonFailClicked]) + button.clicked.connect(self.onButtonClicked) + button.clicked.emit() + view.show() + self.app.exec_() + self.assert_(self.buttonClicked) + +if __name__ == '__main__': + unittest.main() diff --git a/tests/QtDeclarative/connect_python_qml.qml b/tests/QtDeclarative/connect_python_qml.qml new file mode 100644 index 0000000..dbf890f --- /dev/null +++ b/tests/QtDeclarative/connect_python_qml.qml @@ -0,0 +1,20 @@ +import Qt 4.7 + +Rectangle { + id: page + width: 500; height: 200 + color: "lightgray" + + Rectangle { + id: button + width: 150; height: 40 + color: "darkgray" + anchors.horizontalCenter: page.horizontalCenter + y: 150 + MouseArea { + id: buttonMouseArea + objectName: "buttonMouseArea" + anchors.fill: parent + } + } +} |