【问题标题】:How to use QList to keep track of instances of child classes如何使用 QList 跟踪子类的实例
【发布时间】:2017-05-18 11:06:58
【问题描述】:

我有两个类,ParentChild(后者派生自前者),它们都是 QObject 派生类。这些类被实现为树结构上的节点,为每个节点提供特定的功能。在Parent 类下,有一个信号在触发时创建Child 类型的新对象。因此,在三个触发器之后,树结构将如下所示:

家长

---------孩子1

---------儿童(1)

---------儿童(2)

如何使用QList 来跟踪创建的子对象的数量?我想在索引号后面加上名称,这样Child (1) 看起来像Child 1,现在看起来像一个副本。

我已阅读 QList 文档,并且了解如何在对象位于列表中后提取有意义的信息,但我无法找到答案。

编辑:

假设我做了QList<Child*>ListID,这只是将ListID 初始化为指向Parent 类型列表的指针,还是也填充该列表?

有什么建议吗?

PS:我想在开始实施之前知道这一点,因为我想知道我是否以错误的方式进行。这就是为什么我没有要显示的代码。我希望能进行更多的随意讨论。

【问题讨论】:

  • 我不明白你的问题,尤其是“我想在索引号后面加上名称,这样 Child (1) 看起来像 Child 1,现在看起来像副本。”什么看起来像副本?为什么你不能在Parent 类中只保留一个QList<Child> 成员?
  • 那么在Parent 中添加QList<Child*>SomeId 会创建一个父级可访问的子级列表吗?我听起来很愚蠢,但我以前没有使用过 QList。同样Child (1) 看起来像Child 的副本,而不是Child 1。这个例子只是随意的。我需要更详细的功能列表。
  • 我仍然不明白“看起来像副本”是什么意思,但是是的,QList<Child*>SomeId 是要走的路,你分配一个对象,附加一个指向列表的指针,你有您可以跟踪的“孩子”。记得在适当的时候注意删除孩子。如果Child 类很简单,那么使用QList<Child> 可能会更简单。
  • @MichaelThomas 很抱歉跑题了,但是上周你问了很多新手问题。你需要阅读一些关于编程的东西。因为你不知道你在做什么。特别是,阅读一些关于 C++ 及其特性的内容。现在关于主题:使用智能指针,例如 QSharedPointerstd::shared_ptr 作为容器的项目。
  • @DmitrySazonov 我真的很抱歉。我尽量让我的疑虑具体化,并且我真的在努力不发送垃圾邮件。这些问题是新手,因为我刚刚开始学习。我也不期待直接的解决方案。任何阅读材料的链接都非常符合要求。除非有人指出我正确的方向,否则它太大了。我也尝试解决我的问题,而不是等待答案。我希望我没有将自己列入黑名单,不再提问。

标签: c++ qt qlist


【解决方案1】:

一个裸露的QObject 本身就是一个树节点。 是的,QObjectQObjects 的容器!因此,您根本不需要做任何特别的事情,因为它保留了所有直接子代的列表,并且还提供了一种方法递归获取特定类型或名称的所有子节点。

要访问子列表,请使用QObject::children()。要仅获取特定类型的子代,请使用 QObject::findChildren()

在您的情况下,您可以在需要时调用auto list = findChildren<Child*>({}, Qt::FindDirectChildrenOnly) 来获取列表。如果您不想动态分配任何内存,请直接使用QObject 的内部列表:

for (auto objChild : std::as_const(children()))
  if (auto child = qobject_cast<Child*>(objChild)) {
    ...
  }

在 C++-17 之前,使用 qAsConst 而不是 std::as_const

如果您确定只有特定类型的对象是子对象,您可以改用 static_cast 并节省一点运行时间:

for (auto objChild : std::as_const(children())) {
  auto child = static_cast<Child*>(objChild);
  ...
}

Parent 类下有一个信号,在触发时会创建一个Child 类型的新对象。

大概你的意思是一个插槽?

【讨论】:

  • 我做到了。我想说有一个triggered() 信号连接到一个创建Child 类型的新实例的插槽另外,为了澄清,我可以将list 视为普通数组类型对象吗?想获取总数和索引。
  • 在我回答之前:看看它的类型——看看findChildren返回什么类型,然后看看该类型支持什么操作和属性。此外,由于 range-for,您根本不需要关心 list 是否可以为您提供总计数或索引,如果您只需要遍历它(迭代其元素)。
猜你喜欢
  • 2019-11-17
  • 2019-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-03
  • 2015-11-15
相关资源
最近更新 更多