2017-01-26 2 views
1

Je sais, c'est fondamentalement the same question, mais mon problème va plus loin.Promouvoir un widget personnalisé avec un constructeur personnalisé dans QT Creator

L'arbre suivant explique ma structure:

  QWidget 
      | 
     CustomWidget 
     |  | 
    MyTable MyWidgetAroundIt 

Je promu MyTable dans Qt Designer. Donc, je peux l'ajouter à MyWidgetAroundIt. Cela a très bien fonctionné. Le seul problème est, CustomWidget exige qu'il est parent d'être un CustomWidget aussi, son constructeur ressemble:

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

Cela provoque des erreurs de compilation, en tant que concepteur code généré tente d'initialiser MyTable avec un QWidget*, au lieu du CustomWidget*. Que pourrais-je/devrais-je faire pour éviter cela et/ou donner au designer un indice sur cette exigence?

Répondre

3

Un widget dont le parent ne peut pas être QWidget n'est plus un widget. Votre conception rompt le Principe de Substitution de Liskov et doit être réparée.

Vous êtes libre d'activer une fonctionnalité spéciale si le widget se trouve être d'un certain type, mais un widget doit être utilisable avec n'importe quel widget pour un parent.

Ainsi:

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

ou:

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) {} 
}; 
+0

Je compris votre première solution est la voie à suivre. De toute façon, j'ai repensé le design entier et ma valeur spéciale semble être un raccourci facultatif pour les choses que je dois faire. Je me pencherai sur les refactorings possibles pour tout changer aux parents QWidget * standard. Merci d'expliquer de toute façon! Fait un point assez clair! – Migsi

+0

Cela semble être un très bon argument. Cependant, suivant la même logique, ne pouvons-nous pas dire que 'QWidget' casse le principe de liskov en n'autorisant que les parents' QWidget' (et non pas 'QObject')? – Mike

+1

C'est un bug API. Il faudrait des changements minimes à l'architecture de Qt pour corriger cela, mais pour le moment ce n'est pas supporté ([si vous l'essayez, ça va planter] (http://stackoverflow.com/q/28992276/1329652)). Ce ne serait pas un gros problème à régler et je ne le vois pas comme un exemple à suivre. –