The problem here is that you inherit QObject twice: first in ViewInterface hierarchy, second in QDialog hierarchy (diamond problem). Try using virtual inheritance for your FancyView and TextView classes (DOES NOT WORK, SINCE VIRTUAL INHERITANCE SHOULD BE USED IN ENTIRE HIERARCHY)
But there is another problem with your design: both QDialog and QPlainTextEdit inherit QWidget. To resolve this issue you may do the following:
Make ViewInterface abstract without inheriting from QObject. This abstract class will define the interface of your FancyView and TextView and may or may not implement some common logic.
Implement FancyView and TextView with multiple inheritance from QDialog and ViewInterface and from QPlainTextEdit and ViewInterface respectively.
This way you may not encounter any problems with ambiguous base class.
UPDATE:
Did not see your edit yet: indeed this would solve the issue, but
another problem rises: if I do this, I can't use a ViewInterface
pointer to set my QWidget. It is possible indeed, but in my opinion
this is not really clean
Well, that is a real problem. An obvious solution is not to use ViewInterface*
instead of QWidget*
. But this means that you need to change quite a lot of code and it may actually be not that great in your case.
With respect to the given comment, I propose another solution:
Inherit ViewInterface
from QWidget
(with all desired interface functions):
class ViewInterface: public QWidget {
Q_OBJECT
...
}
In ViewInterface
constructor set layout to be used by widget and set it up:
ViewInterface::ViewInterface (QWidget* i_parent)
: QWidget (i_parent) {
auto layout {new QGridLayout (this)};
// Zeroed margins to make full fit.
layout->setContentsMargins (0, 0, 0, 0);
setLayout (layout);
}
In constructors of derived classes add specific widget to layout:
class FancyView : public ViewInterface {
Q_OBJECT
FancyView (QWidget* i_parent)
: ViewInterface (i_parent)
, dialog_widget_ {new QDialog (this)} {
layout->addWidget (dialog_widget_);
}
...
private:
QDialog* dialog_widget_;
}
Implement desired interface using target widget. If you want to process events, you may use QObject::eventFilter (). In this case you should set your FancyView
object from the code above as event filter for dialog_widget_
.
NOTE: In this case you can not use FancyView
as QDialog
. A workabound for this issue is proxy QDialog
signals, slots and public functions and create yet another wrapper class FancyViewDialog
, that works as proxy for the methods, signals and slots in FancyView
. That is not a fantastic solution, but I do not see any other way around diamond problem that allows "is-a" relation between ViewInterface
and QWidget
.