Hello. I'm writing a UI library which uses Qt as a base, and I want each of my widgets to derive from my own version of QWidget which adds some base functionality I want them all to have. But then I run into issues when I want to extend, say, QLineEdit.
I am using Qt but I think this applies to any situation where there's an external API being used. For anyone unfamiliar with Qt, QLineEdit is a "QLineEdit : public QWidget".
So I have something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
class ZWidget : publicvirtual QWidget
{
Q_OBJECT
public:
ZWidget( QWidget * parent = 0 ) : QWidget(parent) {}
// new base functions go here, for example:
void setName( QString const & name );
};
// This is where I get confused
class ZLineEdit : public QLineEdit, public ZWidget
{
Q_OBJECT
public:
// It should still be parentable to a standard QWidget
// What's the proper thing to do here?
ZLineEdit( QWidget * parent = 0 ) : QLineEdit(parent) {}
};
My understanding is normally you'd want to define QLineEdit as a virtual QWidget and take it from there, but I don't have that kind of control in this case. Is there perhaps a different approach I should be considering? My main reason for desiring this is so that I can treat all these widgets in an abstract way (as ZWidgets) in certain situations.
I always thought both classes in the middle of the diamond had to virtually inherit the base class.
As you have have control over ZWidget you can do that - but you are stuck with QLineEdit because
that is part of QT and I'm sure it does not virtually inherit QWidget.
Maybe this will help someone in the future. The solution in this case is to use Qt interfaces. I create an interface class called, say, ZObject, declared it as a Qt Interface and proceed as such:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
class ZObject
{
public:
// interface functions
};
Q_DECLARE_INTERFACE( ZObject, "com.whatever.zobject/1.0" )
class ZWidget : public QWidget, public ZObject
{
Q_OBJECT
Q_INTERFACES( RTObject )
public:
// and so on
};
It's not perfect, but it will suffice. :) I won't be able to replace QWidget with my own extended ZWidget in my widgets as I originally intended, but some important features will be available. For example:
1 2 3 4 5 6 7
QWidget * widget = new ZWidget( parent );
if( qobject_cast<ZObject *>(widget) )
// test passes, ZWidget inherits ZObject
// get a list of all my widgets
// guaranteed to have my new functions
QWidgetList widgets = widget->findChildren<ZObject *>();