2

I know, this is basically the same question, but my problem goes further.

The following tree explains my structure:

         QWidget
            |
       CustomWidget
        |        |
    MyTable  MyWidgetAroundIt

I have promoted MyTable in Qt Designer. So, I can add it to MyWidgetAroundIt. That worked quite well. The only problem is, CustomWidget requires it's parent to be a CustomWidget too, its constructor looks like:

CustomWidget(CustomWidget* parent) : QWidget(parent), _specialValue(parent->getSpecialValue)

This causes compile errors, as the designer generated code tries to initialize MyTable with a QWidget*, instead of the CustomWidget*. What could/should I do to prevent this and/or give the designer a hint about this requirement?

Community
  • 1
  • 1
Migsi
  • 107
  • 2
  • 10

1 Answers1

3

A widget whose parent can't be a QWidget is not a widget anymore. Your design breaks the Liskov Substitution Principle and has to be fixed.

You're free to enable special functionality if the widget happens to be of a certain type, but a widget must be usable with any widget for a parent.

Thus:

CustomWidget(QWidget* parent = nullptr) :
  QWidget(parent)
{
  auto customParent = qobject_cast<CustomWidget*>(parent);
  if (customParent)
    _specialValue = customParent->specialValue();
}

or:

class CustomWidget : public QWidget {
  Q_OBJECT
  CustomWidget *_customParent = qobject_cast<CustomWidget*>(parent());
  SpecialType _specialValue = _customParent ? _customParent->specialValue() : SpecialType();

  SpecialType specialValue() const { return _specialValue; }
public:
  CustomWidget(QWidget * parent = nullptr) : QWidget(parent) {}
};
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • I figured out your first solution is the the way to go. Anyways, I rethought the whole design and my special value seems to be an optional shortkey for the things I've to do. I'll look into possible refactorings to change everything back to standard QWidget* parents. Thank you for explaining anyways! Made a quite clear point! – Migsi Jan 27 '17 at 15:01
  • This sounds like a very good argument. However, following the same logic, can't we say that `QWidget` breaks liskov principle by allowing only `QWidget` parents (and not any `QObject`)? – Mike Mar 03 '17 at 17:32
  • 1
    That's an API bug. It would take minimal changes to Qt's architecture to fix that, but at the moment it's not supported ([if you try it, it'll crash](http://stackoverflow.com/q/28992276/1329652)). It wouldn't be a big deal to fix and I do not think of it as an example to follow. – Kuba hasn't forgotten Monica Mar 03 '17 at 20:06