如何将信号作为函数参数传递?

use*_*792 5 c++ qt

所以我希望制作我们自己的通用继承复选框类,它能够在其构造函数中获取一些值,并以我们需要的方式弹出一个完全连接到我们模型的小部件.

目前我们在视图中做了类似的事情

connect(checkboxWidget, &QCheckbox::Clicked, this, &VMyView::Signal);
Run Code Online (Sandbox Code Playgroud)

单击复选框时,会从VMyView发出信号.

如果我想将该信号作为参数传递到我的新继承类中,并将其连接到自己的connect语句中,我该怎么做?

研究表明我可以传递一个const char*但是我得到了信号/插槽不匹配的编译错误.

CheckBox(View myView, const char* signal)
{
    connect(this, &QCheckBox::Clicked, myView, signal);
}
Run Code Online (Sandbox Code Playgroud)

返回Signal和slot参数不兼容的错误.我也试过SIGNAL(信号)同样的结果.

bna*_*ker 0

我认为这里的主要问题是信号不是静态成员函数。因此,它们需要一个指向该类实例的指针才能正确调用。因此,您不能只传递诸如 之类的内容&VMyView::Signal,因为该函数没有this附加相应的指针。(这就是为什么大多数QObject::connect()重载需要发送者/接收者对象的实例。)

解决此问题的一种方法是创建一个函数对象,其中包含成员函数指针和指向调用该函数的对象的指针。QObject::connect()这可以很好地传递给函数。

这是一个例子:

// objects.h
#include <QtCore>

class Receiver : public QObject
{
    Q_OBJECT
    public:
        Receiver( QObject *parent = nullptr)
            : QObject(parent)
        {
        }

        ~Receiver() { }

    signals:
        void sig(void);
};


class Sender : public QObject
{
    Q_OBJECT
    public:
        Sender(std::function<void(void)> &bound_signal, QObject *parent = nullptr) 
            : QObject(parent)
        {
            // automatically emit `Sender::sig` on a timer, for testing.
            timer = new QTimer(this);
            timer->setInterval(1000);
            QObject::connect(timer, &QTimer::timeout, this, &Sender::sig);
            QObject::connect(this, &Sender::sig, bound_signal);
            timer->start();
        }

        ~Sender() { }

    signals:
        void sig(void);

    private:
        QTimer *timer;
};
Run Code Online (Sandbox Code Playgroud)

然后是一个主函数:

// main.cc
#include <QtCore>

#include "objects.h"

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    Receiver receiver; // object to receive the signal

    // Bind the receiver's signal to the instance of the class
    std::function<void(void)> signal = std::bind(&Receiver::sig, &receiver);

    // Create a Sender, which will connect its own signal to the
    // given bound signal
    Sender sender(signal);

    QObject::connect(&receiver, &Receiver::sig,
            []() -> void { qDebug() << "received"; });
    return app.exec();
}
Run Code Online (Sandbox Code Playgroud)

因此,在您的情况下,Receiver和 它的信号将被替换为VMyView您想要链接的信号,并且Sender将是您已经实现的自定义复选框类。然后在复选框类的构造函数中,将所需的任何信号连接到给定的绑定信号。您还可以传入绑定信号列表,例如std::list<std::function<void(void)>> &bound_signals.

但我不得不说,我不确定这会给你带来什么。您需要在某处编写连接逻辑,但我不明白为什么它需要位于复选框类的构造函数中。无论在何处创建和使用复选框和VMyView类,这似乎都是放置连接代码的更好位置。它更明显、更简单,并且可以更好地分离关注点。复选框类不必知道或关心其连接到的信号/槽。应用程序逻辑(即使用对象的位置)应该定义对象如何彼此交互。