我已经有了更大的项目和架构,并遇到QT信号槽系统的情况,信号非常均匀,问题是:1。许多不同的信号方法,如
signals:
sig_1(bool b);
sig_2(bool b);
...
sig_n(bool b);
或: 2.将差异作为参数发出
signal:
sig(uint n, bool b);
并让slot方法决定n是否适合它的内部值
每个选项都比另一个更差:
情况:发射器是一个微控制器抽象,并获得输入变化的信息。许多插槽类只连接了一个或两个输入,需要了解它们的更改。从结构上讲,发射类不应该依赖于槽类,因此不应该保留它的监听器列表或者包括监听器的公共超类或接口,这就是为什么我坚持使用信号/插槽系统。 / p>
所以我的问题: 在sig / slot系统或moc中是否有某种扩展或参数,或者我在这里完全错过了什么?
答案 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);