5

I am using QObject as a base class for a composite pattern.

Say I have a parent class File (in a contrived example) to which I am adding children of different types, HeaderSection and PageSection. File, HeaderSection and PageSection are all Sections. The constructor for Section takes a parent object which is passed through to QObject's constructor, setting the parent.

e.g:

class Section : public QObject {
 Q_OBJECT

 // parent:child relationship gets set by QObject
 Section(QString name, Section *parent=NULL) : QObject(parent)
 { setObjectName(name);}
 QString name(){return objectName();}
};

class File: public Section {
public:
 // probably irrelevant to this example, but I am also populating these lists
 QList<Section *> headers;
 QList<Section *> pages;
};

class Header : public Section {
Header(QString name, File *file) : Section(name, file){}
};

class Page: public Section {
 Body(QString name, File *file) : Section(name, file){} 
};

Syntax for construction in the definition may be incorrect, apologies, I'm used to doing it outside. Anyway, when I do this:

File *file = new file();
Header *headerA = new Header("Title", file);
Header *headerB = new Header("Subtitle", file);
Page *page1 = new Page("PageOne", file);
Page *page2 = new Page("PageTwo", file);

QList<Page*> pages = file->findChildren<Page*>();

for(int i=0; i < pages.size(); i++)
  qDebug() << pages.at(i)->name();

I get the following output:

Title

Subtitle

PageOne

PageTwo

What am I missing here? Surely if findChildren looked for common base classes then it would only ever return every single child of a Widget (for example), which I know it doesn't in normal use.

Also, if I iterate over the list of children returned and use dynamic_cast<Page*> on each returned child, I get the expected two Page items.

mike
  • 1,192
  • 9
  • 32
  • 2
    add the Q_OBJECT macro at the top of each class – ratchet freak Mar 08 '16 at 14:13
  • Apologies - that is in the full code, I've omitted it here. I'll correct. It's only needed in the base class, btw. – mike Mar 08 '16 at 14:15
  • 2
    @mike: no, it's needed for all classes that derive from QObject - http://stackoverflow.com/questions/3689714/when-should-q-object-be-used ; only deviate from that if you are 100% sure of what you're doing (including 100% sure you're not relying on stuff like `qobject_cast` I believe - but haven't done Qt stuff in a long time) – Mat Mar 08 '16 at 15:10
  • Thanks both you are dead right. – mike Mar 08 '16 at 15:41

1 Answers1

2

The answer is as @Mat and @ratchet freak tell me - I needed Q_OBJECT in every subclass, not just the base class.

mike
  • 1,192
  • 9
  • 32