QT条件信号发射 - 效率

时间:2017-01-10 11:30:55

标签: c++ qt signals-slots qt-signals

我已经有了更大的项目和架构,并遇到QT信号槽系统的情况,信号非常均匀,问题是:1。许多不同的信号方法,如

signals:
sig_1(bool b);
sig_2(bool b);
...
sig_n(bool b);

或: 2.将差异作为参数发出

signal:
sig(uint n, bool b);

并让slot方法决定n是否适合它的内部值

每个选项都比另一个更差:

  1. awefull代码,我更喜欢通用解决方案
  2. 每个插槽都必须检查它的编号是否合适,所以每次O(n)连接都有一行,当moc已经通过一个切换块时我们可以到达O(log n)
  3. 情况:发射器是一个微控制器抽象,并获得输入变化的信息。许多插槽类只连接了一个或两个输入,需要了解它们的更改。从结构上讲,发射类不应该依赖于槽类,因此不应该保留它的监听器列表或者包括监听器的公共超类或接口,这就是为什么我坚持使用信号/插槽系统。 / p>

    所以我的问题: 在sig / slot系统或moc中是否有某种扩展或参数,或者我在这里完全错过了什么?

3 个答案:

答案 0 :(得分:0)

在Qt中有一个名为QSignalMapper的类,它可以帮助管理多对一连接,但是它不能自动解决多对多问题

您可以尝试取消直接(发射器 - 接收器)连接的想法,并尝试在中间使用共享数据向量。仅发出一个信号(“数据更新”)。接收方将收到有关更新的通知,并从共享数据对象中仅提取所需数据(如果不考虑线程安全性,这可以像地图一样简单)。

如果数据向量很小且复制起来相对便宜,你可以简单地将整个向量/映射直接发送给每个人(如上所述,在Qt5直接连接中导致直接函数调用,所以这不是全部慢)

答案 1 :(得分:0)

感谢d.Candela:多对一,多对多的概念对解决问题有一点帮助。我的问题是缺少一对多。该解决方案是模板化的管理器类,仅保留一个稀疏条目为1的矩阵。每一行都是输入值的一部分,并且列以列向量作为订阅者索引来表示订阅者。从这里开始只是移位和屏蔽。因此,管理器中的模板化矢量取代了监听器的插槽,并且信号源已连接到管理器。 如果存在对角化矩阵的特殊情况(仅单位订阅向量),我们可以对其进行排序,然后从O(n)降至O(n ^ -2)。

答案 2 :(得分:0)

您可以创建一个用于管理所有不同信号类型的类,然后在信号中发出该类的对象。插槽可以检查发射的对象,以查看是否需要对其进行处理。示例代码:

struct SignalInfo {
  string description;
  bool value1;
  int value2;
  //Etc
};

那么您的信号签名将是:

void sig(SignalInfo);

,您的广告位可能看起来像这样:

void Handle_signal(SignalInfo info) {
  if (info.description == "type 1") {
    /*do something*/
  }
}

优点是您可以更改SignalInfo类,而无需更改其他任何内容。这样说来,您可以发出并接收对SignalInfo对象的引用,这将使您可以继承SignalInfo的子类,从而获得更大的灵活性。示例信号和插槽签名为:

void sig(SignalInfo&);

void Handle_signal(SignalInfo& info);