为什么 QObject::findChildren 返回具有共同基类的子项?

5
我正在将QObject作为组合模式的基类使用。
假设我有一个父类文件(在一个人为的例子中),我想要添加不同类型的子类,如HeaderSection和PageSection。文件、HeaderSection和PageSection都是Sections。Section的构造函数需要传递一个父对象,该对象会通过QObject的构造函数进行设置,并设置父级对象。
例如:
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){} 
};

在定义中构建语法可能不正确,抱歉,我习惯于在外部进行。无论如何,当我这样做时:

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();

我得到以下输出:
标题
副标题
PageOne PageTwo
我在这里漏掉了什么?如果findChildren寻找共同的基类,那么它只会返回Widget的每个子级,我知道正常使用时它并不是这样的。
此外,如果我遍历返回的子项列表并对每个返回的子项使用dynamic_cast,我将得到预期的两个Page项目。

2
在每个类的顶部添加Q_OBJECT宏。 - ratchet freak
抱歉 - 这段完整代码中有,我在这里省略了它。我会进行更正。顺便提一下,这只需要在基类中使用。 - mike
2
@mike:不,它对所有从QObject派生的类都是必需的- https://dev59.com/uXA65IYBdhLWcg3wrgoa;只有在您100%确定自己在做什么(包括100%确定您不依赖于像`qobject_cast`之类的东西)时才会偏离这一点。我相信-但很久没有做过Qt相关的事情了。 - Mat
感谢您们两位的正确意见。 - mike
1个回答

2
答案就像@Mat和@ratchet freak告诉我的一样 - 我需要在每个子类中都加上Q_OBJECT,而不仅仅是基类。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接