
Originally Posted by
brcain
The following was never really answered ...
see thread for background.
Then maybe you should continue the old thread?

Originally Posted by
brcain
Is it a true statement that "you can't use Qt meta-object system with interface composition"?
It depends how do you define an interface. If an interface is a class that contains only pure abstract methods (like in Java), then the answer is: "no, it isn't true".
But in your case, the "interface" is a class derived from QObject, which obviously doesn't fit that definition.

Originally Posted by
brcain
The Qt documentation implies that multiple inheritance of QObject is not supported.
If the docs say it isn't supported then it means that it isn't supported, but not necessarily that it won't work.
The biggest problem is that each signal or slot is internally represented by a number, so in each of the base classes will use the same number for different slots.
Here's an example of qt_metacall:
int Test
::qt_metacall(QMetaObject::Call _c,
int _id,
void **_a
) {
_id
= QWidget::qt_metacall(_c, _id, _a
);
if (_id < 0)
return _id;
switch (_id) {
case 0: show1(); break;
case 1: show2(); break;
}
_id -= 2;
}
return _id;
}
int Test::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) {
case 0: show1(); break;
case 1: show2(); break;
}
_id -= 2;
}
return _id;
}
To copy to clipboard, switch view to plain text mode
If you have several base classes then it should look like this:
int Test
::qt_metacall(QMetaObject::Call _c,
int _id,
void **_a
) {
if( _id belongs to Base1 ) {
_id = Base1::qt_metacall(_c, _id - base1offset, _a);
}
else if( _id belongs to Base2 ) {
_id = Base1::qt_metacall(_c, _id - base2offset, _a);
}
if (_id < 0)
return _id;
...
}
int Test::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
if( _id belongs to Base1 ) {
_id = Base1::qt_metacall(_c, _id - base1offset, _a);
}
else if( _id belongs to Base2 ) {
_id = Base1::qt_metacall(_c, _id - base2offset, _a);
}
if (_id < 0)
return _id;
...
}
To copy to clipboard, switch view to plain text mode
or:
Test
::qt_metacall(QMetaObject::Call _c,
int _id,
void **_a
){
...
switch (_id) {
case 0: Base1::someSlot1(); break;
case 1: Base2::someSlot2(); break;
...
}
...
}
Test::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
...
if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) {
case 0: Base1::someSlot1(); break;
case 1: Base2::someSlot2(); break;
...
}
...
}
To copy to clipboard, switch view to plain text mode
and of course you will have to write it yourself, as moc won't handle this (it only looks into the first base class).
Another problem is that the QMetaObject for the derived class will be populated only with information about only one base class:
{ &Base1::staticMetaObject, qt_meta_stringdata_Test,
qt_meta_data_Test, 0 }
};
const QMetaObject Test::staticMetaObject = {
{ &Base1::staticMetaObject, qt_meta_stringdata_Test,
qt_meta_data_Test, 0 }
};
To copy to clipboard, switch view to plain text mode
While it should be something like this:
const QMetaObject * otherBaseClasses
[] = { &Base2
::staticMetaObject,
0 };
{ &Base1::staticMetaObject, qt_meta_stringdata_Test,
qt_meta_data_Test, otherBaseClasses }
};
const QMetaObject * otherBaseClasses[] = { &Base2::staticMetaObject, 0 };
const QMetaObject Test::staticMetaObject = {
{ &Base1::staticMetaObject, qt_meta_stringdata_Test,
qt_meta_data_Test, otherBaseClasses }
};
To copy to clipboard, switch view to plain text mode
In other words, you will have to do all of the work that moc does for you, it it's going to work.
Bookmarks