【问题标题】:How to handle signals when a widget has many child widgets当小部件有许多子小部件时如何处理信号
【发布时间】:2014-03-13 07:52:10
【问题描述】:

我正在设计一款包含世界地图小部件的游戏;这个小部件有 100 多个区域小部件作为其子级。还有一个单独的信息面板小部件。当我单击一个区域时,我希望该信息被发送并显示在信息面板上。到目前为止,我的想法给了我两个选择:

  1. 将 100 多个区域中的每一个连接到信息面板。这对我来说似乎很难看,因为我觉得信息面板应该只知道世界地图小部件,而不是它的内部工作原理(例如孩子)。

  2. 将 100 多个区域中的每一个连接到地图小部件,然后拥有地图 发送另一个信号以被游戏中的其他小部件(例如信息面板)接收。就拥有独立的小部件而言,这似乎更好,但需要 2 个信号而不是 1 个。

其中一种方法比另一种更可取吗?还是我完全错过了另一种解决方案?

【问题讨论】:

    标签: qt pyqt signals-slots


    【解决方案1】:

    我曾经在一家生产自己的地理空间信息系统 (GIS) 产品的公司工作,我们也有使用 Qt 的确切用例。

    根据我的经验,我们将使用选项 #2,因为它封装了信息面板(即 视图)和世界地图(即 模型 之间的细节和关系)。

    将来,您的世界地图可能会包含多个可选区域,而信息面板可能不想开始了解您的所有不同实体世界地图来显示它们。所以是的,虽然 #2 会产生一些额外的信号,但从封装和扩展的角度来看,它可能会更好。

    例如,将信息面板连接到您的世界地图中有关选定实体而不是区域的信号。当然 region is 一个 entity 并且直接使用 region 可以工作,但在未来也许你的世界地图会有可选择的建筑物标记车辆等...

    connect( mapWidget, SIGNAL( selectedEntityChanged( MapEntity* ) ), 
             infoPanel, SLOT( onSelectedEntityChanged( MapEntity* ) ) );
    

    通过这种方式,您的信息面板可以设计为一般显示有关实体的信息,区域也是从该实体派生的。如果您想在地图中添加一个 vehicle 并使其信息面板可以显示它,您所要做的就是从 派生您的 vehicle >实体,你会很高兴的。

    欢迎来到 StackOverflow!

    【讨论】:

    • 谢谢!我没有考虑将来可能的扩展,但这很有意义。以一种防止它在未来变得丑陋的方式编写代码是非常值得的。
    • @TheBeardedTemplar 很高兴我能帮上忙。我稍微更新了答案,但基本上你要确保你有强大的接口和/或抽象基类,这样你就可以让你的小部件在泛型类型上工作,而不是尽可能地在非常具体的实现上工作。祝你好运!
    【解决方案2】:

    请记住,每个 QObject 都带有一个属性系统 - 一个通用的、类似 Python 的键值存储。键是字符串,值是变体。由于QWidgetQObject,您可以利用它。就其本身而言,这使得QSignalMapper 变得非常多余。

    您也可以使用未记录但稍快的userData mechanism - 它使用整数键而不是字符串键。唯一的 key id 是通过registerUserData() 获得的,其他方面的语义与QEvent::registerEventType 相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多