Fixed the number of dynamic signal to 50, to avoid index error on

QMetaObject functions.

Reviewed by Hugo Parente <hugo.lima@openbossa.org>
This commit is contained in:
Renato Filho 2010-02-18 11:14:41 -03:00 • committed by Marcelo Lira
commit b2c5e91ff7
3 changed files with 42 additions and 8 deletions

View file

@ -56,8 +56,7 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject
if (usingGlobalReceiver) { if (usingGlobalReceiver) {
signalManager.addGlobalSlot(slot, callback); signalManager.addGlobalSlot(slot, callback);
} else { } else {
PySide::DynamicQMetaObject* dynMetaObj = reinterpret_cast<PySide::DynamicQMetaObject*>(const_cast<QMetaObject*>(metaObject)); PySide::SignalManager::registerMetaMethod(receiver, slot, QMetaMethod::Slot);
dynMetaObj->addSlot(slot);
} }
slotIndex = metaObject->indexOfSlot(slot); slotIndex = metaObject->indexOfSlot(slot);
} }

View file

@ -41,6 +41,8 @@
#include <QDebug> #include <QDebug>
#include <QMetaMethod> #include <QMetaMethod>
#define MAX_SIGNALS_COUNT 50
using namespace PySide; using namespace PySide;
static int registerString(const QByteArray& s, QList<QByteArray>* strings) static int registerString(const QByteArray& s, QList<QByteArray>* strings)
@ -74,6 +76,11 @@ DynamicQMetaObject::~DynamicQMetaObject()
void DynamicQMetaObject::addSignal(const char* signal) void DynamicQMetaObject::addSignal(const char* signal)
{ {
if (m_signals.size() >= MAX_SIGNALS_COUNT) {
qWarning() << "Fail to add dynamic signal to QObject. PySide support at most" << MAX_SIGNALS_COUNT << "dynamic signals.";
return;
}
m_signals << QByteArray(signal); m_signals << QByteArray(signal);
updateMetaObject(); updateMetaObject();
} }
@ -93,9 +100,12 @@ void DynamicQMetaObject::removeSlot(uint index)
void DynamicQMetaObject::removeSignal(uint index) void DynamicQMetaObject::removeSignal(uint index)
{ {
//Current Qt implementation does not support runtime remove signal
/*
QMetaMethod m = method(index); QMetaMethod m = method(index);
if (m_signals.removeAll(m.signature())) if (m_signals.removeAll(m.signature()))
updateMetaObject(); updateMetaObject();
*/
} }
void DynamicQMetaObject::updateMetaObject() void DynamicQMetaObject::updateMetaObject()
@ -114,7 +124,7 @@ void DynamicQMetaObject::updateMetaObject()
MethodScriptable = 0x40 MethodScriptable = 0x40
}; };
uint n_signals = m_signals.count(); uint n_signals = MAX_SIGNALS_COUNT;
uint n_methods = n_signals + m_slots.count(); uint n_methods = n_signals + m_slots.count();
int header[] = {5, // revision int header[] = {5, // revision
0, // class name index in m_metadata 0, // class name index in m_metadata
@ -123,9 +133,7 @@ void DynamicQMetaObject::updateMetaObject()
0, 0, // prop count and prop indexes 0, 0, // prop count and prop indexes
0, 0, // enum count and enum index 0, 0, // enum count and enum index
0, 0, // constructors 0, 0, // constructors
0, // flags MAX_SIGNALS_COUNT};
n_signals // signalCount
};
const int HEADER_LENGHT = sizeof(header)/sizeof(int); const int HEADER_LENGHT = sizeof(header)/sizeof(int);
header[5] = HEADER_LENGHT; header[5] = HEADER_LENGHT;
@ -141,13 +149,21 @@ void DynamicQMetaObject::updateMetaObject()
int index = HEADER_LENGHT; int index = HEADER_LENGHT;
//write signals //write signals
foreach(QByteArray signal, m_signals) { QLinkedList<QByteArray>::iterator iSignal = m_signals.begin();
data[index++] = registerString(signal, &strings); // func name for(int i=0; i < MAX_SIGNALS_COUNT; i++) {
if (iSignal != m_signals.end()) {
data[index++] = registerString(*iSignal, &strings); // func name
iSignal++;
} else {
data[index++] = NULL_INDEX; // func name
}
data[index++] = NULL_INDEX; // arguments data[index++] = NULL_INDEX; // arguments
data[index++] = NULL_INDEX; // normalized type data[index++] = NULL_INDEX; // normalized type
data[index++] = NULL_INDEX; // tags data[index++] = NULL_INDEX; // tags
data[index++] = AccessPublic | MethodSignal; // flags data[index++] = AccessPublic | MethodSignal; // flags
} }
//write slots //write slots
foreach(QByteArray slot, m_slots) { foreach(QByteArray slot, m_slots) {
data[index++] = registerString(slot, &strings); // func name data[index++] = registerString(slot, &strings); // func name
@ -164,6 +180,7 @@ void DynamicQMetaObject::updateMetaObject()
str.append(signature); str.append(signature);
str.append(char(0)); str.append(char(0));
} }
delete[] d.stringdata; delete[] d.stringdata;
char* stringData = new char[str.count()]; char* stringData = new char[str.count()];
std::copy(str.begin(), str.end(), stringData); std::copy(str.begin(), str.end(), stringData);

View file

@ -9,6 +9,10 @@ from PySide.QtCore import *
class Foo(QFile): class Foo(QFile):
pass pass
class DynObject(QObject):
def slot(self):
pass
class qmetaobject_test(unittest.TestCase): class qmetaobject_test(unittest.TestCase):
def test_QMetaObject(self): def test_QMetaObject(self):
qobj = QObject() qobj = QObject()
@ -27,6 +31,20 @@ class qmetaobject_test(unittest.TestCase):
fm = f.metaObject() fm = f.metaObject()
self.assertEqual(m.methodCount(), fm.methodCount()) self.assertEqual(m.methodCount(), fm.methodCount())
def test_DynamicSlotSignal(self):
o = DynObject()
o2 = QObject()
method_count_base = o.metaObject().methodCount()
o.connect(o2, SIGNAL("bar()"), o.slot)
slot_index = o.metaObject().indexOfMethod("slot()")
o.connect(o, SIGNAL("foo()"), o2, SIGNAL("bar()"))
signal_index = o.metaObject().indexOfMethod("foo()");
self.assert_(slot_index != signal_index)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()