PDA

View Full Version : QObject inherittance problems



KShots
24th April 2007, 14:05
I'm just having trouble coming to grips with this issue. At the moment, I'm trying to figure out how to implement a widget base class that can be sub-classed by either a QWidget-based class or a QGLWidget-based class. I can't figure out how to implement such a structure :(. Here's the problem:


.
+-----------------+
| Abstract Base |
| Class |
+-----------------+
/ \
/ \
/ \
/ \
+-----------------+ +------------------+
| QWidget-based | | QGLWidget-based |
| class | | class |
+-----------------+ +------------------+The abstract base class would include signals and slots that its sub-classes would implement. This creates a problem. If I were to say that the abstract base class inheritted QWidget, I can make the QWidget subclass work, but not the QGLWidget. If I were to say that the abstract base class inheritted QGLWidget, I can make the QGLWidget subclass work, but not the QWidget subclass. If I were to simply make the abstract base class inherit QObject, neither would work. Any idea how to resolve such a thing?

I can't get rid of all reference to a QObject ancestor because I require the virtual signals and slots inherittance.

wysota
24th April 2007, 14:34
In general you can't do it this way. In this situation the base class can't inherit QObject. Maybe instead of inheritance you should use some other association? For example a has-a relationship? Could you explain what you're trying to do?

KShots
24th April 2007, 14:49
basically, what I'm trying to do is define an interface that a bunch of plugins should follow. Each plugin should implement a series of slots. If they fail to do so, they need to produce a compile-time error. Theoretically, I could do this by not inheritting the base class at all and implementing the slots in the individual plugins, but if a plugin fails to implement a slot, it will still compile and run with weird results.

Here's the structure of what I've got:
.
+------------------+ +--------------------------------+
| Plugin Interface | | Abstract base class with slots |
+------------------+ +--------------------------------+
| |
+------------------+ +------------------------------+
| Plugins (a,b...) |---------| QWidget/QGLWidget sub-class |
+------------------+ +------------------------------+The section on the right is a simplified version of my previous diagram. My plugin has a "has a" relationship with the QWidget / QGLWidget class, which it would return on request (effectively bypassing the plugin itself requiring QWidget, and theoretically allowing the QWidget to have abstract slots defined that all plugins should follow).

KShots
24th April 2007, 14:57
Ok, I think I can get away with this if I seperate things one more step further:
.
+-----------+ +-------------------+ +------------------+
| Plugin | | Abstract class | | Abstract base |
| Interface | | knows about slots | | class with slots |
+-----------+ +-------------------+ +------------------+
| | |
+---------+ +-------------------+ +----------------+
| Plugins |----| QWidget/QGLWidget |-| plugin slots |
| (a,b...)| | sub-class | | implementation |
+---------+ +-------------------+ +----------------+This way, my plugin can pass a QWidget, which would have an implementation class of slots. I think the nature of my slots would allow such a relationship. It may get tricky, depending on the plugin, as far as gaining access to the QWidget itself (perhaps a pointer to the QWidget sub-class in the slots implementation?), but I think it's doable. The "abstract class that knows about slots" does not inherit QObject or similar, but it knows about the abstract base class with slots (and includes it as a pointer variable).

EDIT: This structure compiles. I think I have a solution. Thanks for the idea :).

Eldritch
24th April 2007, 16:29
I'm going to skip drawing the ASCII art here. :P

But, I've done something similar using a template as my base class. It may hamper usage of signals and slots, though -- haven't tested that.

The 'leaf' classes inherit the template, which has two arguments: the QWidget-based class and the plugin interface:

template<class QW, class PI>
MyMixer
{
};

then

class MyWidgetWithCoolStuff : public MyMixer<QWidget, PlugIn>
{
Q_OBJECT
};

...

class MyOtherWidgetWithCoolStuff : public MyMixer<QGLWidget, PlugIn>
{
Q_OBJECT
};

As I said... I haven't had the need to use signals / slots with this, so I wouldn't be surprised of moc has trouble with it. In my case, I have several separate "mixin" interfaces that one can pair with a QWidget-based window, and the template implements all the common code.

Fun! Fun! FUN!!!
:D