1

考虑接收信号的信号管理器,检查某些条件,如果满足,则将信号传输到槽,否则丢弃信号:

信号(一些参数)---> [经理] ---> 插槽(一些参数)

我可以使用 QMetaObject::invokeMethod 为每个给定的参数集实现它,比如 void signal(int) 和 void slot(int):

。H

class Manager: public QObject
{
    Q_OBJECT
public:
    Manager(QObject* sender,const char* signal, QObject* recv, const char* slot);
private:
    bool isOkToSend();

    QString slotInvokeSyntax;
    QObject *recv;

private slots:
    On_Signal(int);
}

.cpp

Manager::Manager(QObject* sender,const char* signal, QObject* recvIn, const char* slot)
        : slotInvokeSyntax(slot)
        , recv(recvIn)
{
    connect(sender,signal,this,SLOT(On_Signal(int));
    //retrieving method name only
    slotInvokeSyntax.remove(0,1).remove(QRegExp("(*",Qt::CaseSensitive,QRegExp::Wildcard));
} 

Manager::On_Signal(int val)
{
    //invoking slot
    if(isOkToSend())
        QMetaObject::invokeMethod(recv,slotInvokeSyntax.toAscii().constData(),Q_ARG(int,val));
}

我想以某种方式将其推广到具有通用参数数量/类型的信号和插槽 - 这样管理器就可以处理任何对,如信号(QString)-插槽(QString),信号(int,int)-slot(int,int) , ...

有没有什么方法可以在不为 Manager 中的每个参数类型添加插槽的情况下实现此功能?如果我的方法总体上是错误的,欢迎就如何实施此类管理器提出任何建议!

编辑

关于我要实现的内容的一点说明 - 我有一个大型系统,它有几个可能的状态,由许多较小的小部件(或子系统)组成(一些子系统也可以作为独立应用程序或作为更大的系统)。我正在尝试实现拦截某些 ui 事件(例如按钮单击、QLineEdit 中的编辑、QDropbox 更改等)的全局观察者,并且要么让小部件的相应插槽被调用,要么在所需的操作干扰时丢弃它系统的全局状态。我想通过拦截信号来做到这一点,因为它可以避免系统组件之间的依赖关系并将每个子系统编译为独立库(观察者不依赖于系统的任何其他部分,因此被放入核心库中),但是我'

4

1 回答 1

1

仅供参考,每当你使用这样的东西时:

QString foo;
something(foo.toAscii().constData());

...您正在访问已释放的内存,因为 指向的数据QByteArray::constData仅在QByteArray实例存在且未被修改之前有效。在您的情况下, theQByteArray是通过调用创建的临时对象,foo.toAscii()并在调用之前被销毁something。所以这会在某个时候崩溃。 编辑:这不适用于函数调用,请参阅评论。

对于您的问题 - 知道您在这里想要实现的目标会很有趣。Qt 的元类型和元对象系统确实是一个丰富的系统,但过度滥用它可能不是解决问题的最优雅的方式。也就是说,在模拟对象、单元测试等中以这种“创造性”的方式使用它可能很好。

我自己没有这样做,我不确定它是否可行而不必触摸q_static_metacall,但看起来QObject 通用信号处理程序包含对您问题的答案。

编辑后:

您说您正在寻找类似通用事件总线的东西;所谓的原因是为了避免在个别组件发生变化时过度重建。我不会在这个架构中引入中央拦截器。如果状态的总量相当小,为什么不让某些东西在进入特定状态时发出信号,并通过启用/禁用单个QActions 来让所有组件对此做出反应?

于 2013-04-30T09:08:27.450 回答