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>
This commit is contained in:
parent
a1524b78b6
commit
bd8239b1cd
6 changed files with 66 additions and 10 deletions
|
|
@ -32,7 +32,8 @@ static bool qobjectConnect(QObject* source, const char* signal, QObject* receive
|
||||||
return false;
|
return false;
|
||||||
signal++;
|
signal++;
|
||||||
|
|
||||||
PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal);
|
if (!PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal))
|
||||||
|
return false;
|
||||||
|
|
||||||
bool isSignal = PySide::isSignal(slot);
|
bool isSignal = PySide::isSignal(slot);
|
||||||
slot++;
|
slot++;
|
||||||
|
|
@ -46,7 +47,9 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject
|
||||||
return false;
|
return false;
|
||||||
signal++;
|
signal++;
|
||||||
|
|
||||||
PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal);
|
if (!PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal))
|
||||||
|
return false;
|
||||||
|
|
||||||
int signalIndex = source->metaObject()->indexOfMethod(signal);
|
int signalIndex = source->metaObject()->indexOfMethod(signal);
|
||||||
|
|
||||||
PySide::SignalManager& signalManager = PySide::SignalManager::instance();
|
PySide::SignalManager& signalManager = PySide::SignalManager::instance();
|
||||||
|
|
@ -70,7 +73,8 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject
|
||||||
if (usingGlobalReceiver) {
|
if (usingGlobalReceiver) {
|
||||||
signalManager.addGlobalSlot(slot, callback);
|
signalManager.addGlobalSlot(slot, callback);
|
||||||
} else {
|
} else {
|
||||||
PySide::SignalManager::registerMetaMethod(receiver, slot, QMetaMethod::Slot);
|
if (!PySide::SignalManager::registerMetaMethod(receiver, slot, QMetaMethod::Slot))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
slotIndex = metaObject->indexOfSlot(slot);
|
slotIndex = metaObject->indexOfSlot(slot);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -523,6 +523,8 @@ char* getTypeName(PyObject* type)
|
||||||
return typeName;
|
return typeName;
|
||||||
} else if (PyString_Check(type)) {
|
} else if (PyString_Check(type)) {
|
||||||
return strdup(PyString_AS_STRING(type));
|
return strdup(PyString_AS_STRING(type));
|
||||||
|
} else if (type == Py_None) {
|
||||||
|
return strdup("void");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -537,7 +539,7 @@ char* signalBuildSignature(const char *name, const char *signature)
|
||||||
char* signalParseSignature(PyObject *args)
|
char* signalParseSignature(PyObject *args)
|
||||||
{
|
{
|
||||||
char *signature = 0;
|
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);
|
return getTypeName(args);
|
||||||
|
|
||||||
for(Py_ssize_t i = 0, i_max = PySequence_Size(args); i < i_max; i++) {
|
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;
|
item->d = new PySideSignalInstanceDataPrivate;
|
||||||
PySideSignalInstanceDataPrivate* selfPvt = item->d;
|
PySideSignalInstanceDataPrivate* selfPvt = item->d;
|
||||||
selfPvt->source = source;
|
selfPvt->source = source;
|
||||||
const char* cppSignature = m.signature();
|
QByteArray cppName(m.signature());
|
||||||
|
cppName = cppName.mid(0, cppName.indexOf('('));
|
||||||
// separe SignalName
|
// separe SignalName
|
||||||
selfPvt->signalName = strdup(cppSignature);
|
selfPvt->signalName = strdup(cppName.data());
|
||||||
char* endName = strchr(selfPvt->signalName, '(');
|
selfPvt->signature = strdup(m.signature());
|
||||||
endName = '\0';
|
|
||||||
selfPvt->signature = strdup(cppSignature);
|
|
||||||
selfPvt->homonymousMethod = 0;
|
selfPvt->homonymousMethod = 0;
|
||||||
selfPvt->next = 0;
|
selfPvt->next = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -482,7 +482,7 @@ bool SignalManager::registerMetaMethod(QObject* source, const char* signature, Q
|
||||||
if (methodIndex == -1) {
|
if (methodIndex == -1) {
|
||||||
Shiboken::SbkBaseWrapper* self = (Shiboken::SbkBaseWrapper*) Shiboken::BindingManager::instance().retrieveWrapper(source);
|
Shiboken::SbkBaseWrapper* self = (Shiboken::SbkBaseWrapper*) Shiboken::BindingManager::instance().retrieveWrapper(source);
|
||||||
if (!self->containsCppWrapper) {
|
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;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
PySide::DynamicQMetaObject* dynMetaObj = reinterpret_cast<PySide::DynamicQMetaObject*>(const_cast<QMetaObject*>(metaObject));
|
PySide::DynamicQMetaObject* dynMetaObj = reinterpret_cast<PySide::DynamicQMetaObject*>(const_cast<QMetaObject*>(metaObject));
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
PYSIDE_TEST(qdeclarativenetwork_test.py FALSE)
|
PYSIDE_TEST(qdeclarativenetwork_test.py FALSE)
|
||||||
PYSIDE_TEST(qdeclarativeview_test.py FALSE)
|
PYSIDE_TEST(qdeclarativeview_test.py FALSE)
|
||||||
|
PYSIDE_TEST(connect_python_qml.py FALSE)
|
||||||
|
|
|
||||||
30
tests/QtDeclarative/connect_python_qml.py
Executable file
30
tests/QtDeclarative/connect_python_qml.py
Executable file
|
|
@ -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()
|
||||||
20
tests/QtDeclarative/connect_python_qml.qml
Normal file
20
tests/QtDeclarative/connect_python_qml.qml
Normal file
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue