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

时间:2017-11-03 18:48:39

标签: c++ qt

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

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

connect(checkboxWidget, &QCheckbox::Clicked, this, &VMyView::Signal);

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

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

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

实施例

CheckBox(View myView, const char* signal)
{
    connect(this, &QCheckBox::Clicked, myView, signal);
}

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

2 个答案:

答案 0 :(得分:1)

最终解决方案最终变得相当简单

而不是在我的视图中使用它

connect(pCheckbox, &QCheckBox::clicked, this, &MyView::Signal);

我用

    connect(this, &QCheckBox::clicked, View, signal);

信号通过函数指针进入我的函数

MyCheckBox::MyCheckBox(QWidget* parent, MyView* View, void(MyView::*signal)(bool))

关键点是

void(MyView::*signal)(bool) 

也相等

&MyView::Signal

答案 1 :(得分:0)

我认为这里的主要问题是信号不是静态成员函数。因此,它们需要一个指向要正确调用的类实例的指针。因此,您不能只传递const ListItem = ({ servicio }) => { const { nombre, created_at, estatus } = servicio; const { thumbnailStyle, headerContentStyle, thumbnailContainerStyle, headerTextStyle, imageStyle } = styles; return ( <Card> <CardSection> <View style={thumbnailContainerStyle}> <Text style={headerTextStyle}>{nombre}</Text> </View> <View style={headerContentStyle}> <Switch value={estatus}/> </View> </CardSection> </Card> ); export default ListItem; 之类的内容,因为没有相应的&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;
};

因此,在您的情况下,// 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(); } 及其信号将被Receiver替换为您想要链接的信号,而VMyView将是您自定义的复选框类实现。然后在复选框类的构造函数中,将您想要的任何信号连接到给定的绑定信号。您还可以传入绑定信号列表,例如Sender

不过,我不得不说,我不确定这会给你买什么。您需要在某处编写连接逻辑,我不明白为什么它需要在复选框类的构造函数中。无论在何处创建和使用复选框和std::list<std::function<void(void)>> &bound_signals类,这似乎是放置连接代码的更好位置。它更明显,更少复杂,并且可以更好地分离关注点。复选框类不必知道或关心它所连接的信号/插槽。应用程序逻辑(即,对象使用的位置)应定义对象如何相互交互。