[Kde-bindings] Hacking moc-generated code

Ashley Winters jahqueel at yahoo.com
Wed Aug 31 06:15:02 UTC 2005


--- Eric Jardim <ericjardim at gmail.com> wrote:
> 
> All, I know that everything points to this
> "qt_metacall(QMetaObject::Call 
> _c, int _id, void **_a)" function, but it is a little hard to
> understand the 
> code.

Here's how I would document Qt4's qt_metacall:

qt_metacall: Calls a QObject-derived method published by a QMetaObject

@param _c      The type of call to make. See the {@link
QMetaObject::Call} enum for valid types
@param _id     The index of the method to call. Each class which
inherits from QObject appends its list of signals/slots to its
superclass' list by creating a new QMetaObject. Every possible signal
or slot which can be metacalled has a unique id within that class, as
if it was an index into a function-pointer array which includes all
meta-functions in itself and its superclasses.
@param _a      An array of pointers to arguments from the signal.

Details:

_c -- This documentation mainly covers QMetaObject::InvokeMetaMethod

_id -- Lets say your class inherits from QWidget and wants to publish a
function via QMetaObject. When Qt wants to invoke your meta-method, it
will actually pass you a number like _id=18, but you can't know whether
that number refers to the function *you* should be handling until you
ask your superclass whether it wants to handle it, first. That's why
the beginning of each qt_metacall() has a call to the super-class
QMetaObject -- it's a recursive unstacking of the meta-index.

Imagine if our hierarchy defines this many meta-methods for each class:

QObject:  2
QWiidget: 15
MyClass:  1

In order to call the one slot defined in MyClass, Qt will pass _id=18
to MyClass::qt_metacall(). The first thing every qt_metacall() does is
call its superclass function, which means _id=18 gets all the way up to
QObject. Since 18 > 2, QObject::qt_metacall() knows the call is for a
subclass, and it returns _id - 2. After QObject returns to
QWidget::qt_metacall(), _id is now 16, which is also out of range for
QWidget. QWidget returns _id - 15 to MyClass, which now has an _id of
1. At this point the index *is* in range, and MyClass knows to call its
slot. If _id was still out of range, MyClass would return _id - 1 so
any of its subclasses could add slots of their own.

_a -- The argument list. Each signal populates an array with pointers
to all its arguments and an optional (first element) return value,
something like so:

int MyClass::mysignal(int _a1, const char *_a2, const QString &_a3) {
    int _ret;
    void *_a[] = { &_ret, &_a1, &_a2, &_a3 };
    QMetaObject::activate(..., _a);
    return ret;
}

In order to call a method (or a scripting-language function) given an
_a  pointer-list, you dereference each argument pointer to the
necessary type (which you can dynamically discover from QMetaMethod, if
you like) and pass it to the method you want to call in Python, in
O'Caml, or in C++:

*(int*)_a[0] =
    obj->myslot(*(int*)_a[1],
           *(const char**)_a[2],
           *(const QString*)_a[3]);

Ashley Winters


		
__________________________________ 
Do you Yahoo!? 
Read only the mail you want - Yahoo! Mail SpamGuard. 
http://promotions.yahoo.com/new_mail 



More information about the Kde-bindings mailing list