在Qt中创建动态插槽

在Qt中创建动态插槽,qt,dynamic,signals-slots,Qt,Dynamic,Signals Slots,我正在尝试动态创建插槽并连接它们。我能够动态创建按钮,并将它们与现有插槽连接。但是如果我有一个包含一些成员函数的类,并且我想将这些函数用作插槽,该怎么办呢 从一般的角度来看,我想创建一个模板,用于在给定函数指针的情况下生成插槽。这允许我们在不更改现有代码的情况下创建插槽,并且不必使用MOC重新编译。 如果这不合理,请告诉我。多谢各位 -CV它确实很有意义。我想这不是你想要的。如果您的函数没有参数,那么像这样的东西就足够了: class SlotForwarder : public QObject

我正在尝试动态创建插槽并连接它们。我能够动态创建按钮,并将它们与现有插槽连接。但是如果我有一个包含一些成员函数的类,并且我想将这些函数用作插槽,该怎么办呢

从一般的角度来看,我想创建一个模板,用于在给定函数指针的情况下生成插槽。这允许我们在不更改现有代码的情况下创建插槽,并且不必使用MOC重新编译。 如果这不合理,请告诉我。多谢各位


-CV

它确实很有意义。我想这不是你想要的。如果您的函数没有参数,那么像这样的东西就足够了:

class SlotForwarder : public QObject
{
    Q_OBJECT

public:

    typedef void (*Function)(); // or whatever. I never get this syntax right...

    SlotForwarder(Function function, QObject* parent = 0) 
        : QObject(parent)
        , m_fptr(function)
    {}

public slots:

    void forward()
    {
        m_fptr();
    }

private:

    Function m_fptr;
};
为要封装的每个函数创建一个函数,并像往常一样连接到
转发


现在,如果他们有争论,也许这篇Qt季刊文章会有所帮助

该技术包括自己重新实现
qt_metacall
方法。该方法具有以下签名:

int QObject::qt_metacall(QMetaObject::Call call, int id, void **arguments)
调用是一种元调用:插槽、信号、属性读取或写入等。每个插槽都有一个id。参数被压缩(按值或作为指针)在参数数组中。阅读moc生成的代码是理解其工作原理的好方法


有关原始函数签名的数据仅在编译时可用,但插槽在运行时解析。由于这种不匹配,您需要将函数包装为模板适配器类型,该类型为
qt_metacall
的实现提供一个常量接口,并将
参数
数组转换为函数可以理解的内容(参见Python操作符)。这是andref代码的延续,以便使用任何成员函数作为插槽

    class SlotForwarder : public QObject
    {
        Q_OBJECT

    public:

        typedef void (*Function)();

        SlotForwarder(Function function, QObject* parent = 0) 
            : QObject(parent)
            , m_fptr(function)
        {}

    public slots:

        void forward()
        {
            m_fptr();
        }

    private:

        Function m_fptr;
    };

    int main(){
      QApplication a(argc, argv);
      MyClass myClassObject; //contains a function called MemberFunc
      //create a slotforwarder object so 
      SlotForwarder *memberFuncSlot = new SlotForwarder (std::tr1::bind(&MyClass::MemberFunc, &myClassObject));
      QObject::connect(ui.button,SIGNAL(clicked()),memberFuncSlot,SLOT(forward());
    }

谢谢你的密码。这应该适用于正常函数,但不适用于成员函数。你知道一个类成员函数的实现方法吗?谢谢andref。我发现成员函数部分使用tr1::bind。我已经在下面发布了我的代码。一旦我有了一个用于动态UI创建的小应用程序(包括动态信号/插槽连接),我就会发布一个链接。哇<代码>tr1::bind很棒,我已经完全忘记了它。有趣的方法是,在普通程序中何时删除转发器。我想聪明的指针会更明智