Qt 我们如何用不同的参数连接信号和插槽?

Qt 我们如何用不同的参数连接信号和插槽?,qt,qt4,Qt,Qt4,在Qt中,信号和插槽需要匹配的参数类型: QObject::connect:不兼容的发送方/接收方参数QLabel::linkActivated(QString)-->Button::call(int) 如何实现这样的组合?一个简单的方法是使用一个中间插槽来调用所需的插槽。e、 g connect(src, SIGNAL(linkActivated(QString)), this, SLOT(receiveLink(QString))); 然后 void receiveLink(QString

在Qt中,信号和插槽需要匹配的参数类型:

QObject::connect:不兼容的发送方/接收方参数QLabel::linkActivated(QString)-->Button::call(int)


如何实现这样的组合?

一个简单的方法是使用一个中间插槽来调用所需的插槽。e、 g

connect(src, SIGNAL(linkActivated(QString)), this, SLOT(receiveLink(QString)));
然后

void receiveLink(QString blah)
{
  int response = someFunction(blah);
  mybutton->call(response);
}
您必须定义某种方法来将字符串解释为int。

来自:

信号的签名必须与接收信号的签名相匹配 狭槽(事实上,插槽的签名可能比其上的信号短。) 接收,因为它可以忽略额外的参数。)

这意味着

信号(int、int、QString

只能与具有以下签名的插槽连接

slot1(int, int, QString)
slot2(int, int)
slot3(int)
slot4()

正如koan所建议的,最好的方法是使用另一个带有QString参数的插槽,然后调用实际需要的插槽。

插槽参数的默认值非常有用。这允许将具有不同签名的信号连接到插槽(反之亦然,连接到@pnezis answer):

可以连接到不同的信号:

signal1(int, int, QString)
signal2(int, int)
signal3(int)
signal4()

此外,Qt 4.8建议了有用的类:

此类收集一组无参数信号,并使用与发送信号的对象对应的整数、字符串或小部件参数重新发送这些信号

但仅针对一个参数:

QSignalMapper* mapper = new QSignalMapper(this) ;

connect(action, SIGNAL(triggered()), mapper, SLOT(map())) ;
mapper->setMapping(action, "param value") ;

connect(mapper, SIGNAL(mapped(const QString &)),
  this, SIGNAL(clicked(const QString &)));

作为补充,如果不想编写中间槽,可以使用lambda表达式(当然支持C++11)调用该方法。但是,连接器类必须知道这些特定信号和插槽中使用的参数类型

举个例子,假设您试图将参数类型为
QString
的信号连接到参数类型为
char
的插槽,您可以这样做

class SignalClass{
signals:
    void testSignal(QString tString);
};

class SlotClass{
public slots:
    void testSlot(char tChar);
};

class ConnectorClass{
public:
    void connectSignalAndSlot () {
        SignalClass tSigClass;
        SlotClass tSlotClass;
        connect(&tSigClass, &SignalClass::testSignal,
                [=](QString tString) { this->metaObject()->invokeMethod(tSlotClass,"testSlot", Q_ARG(char, tString.at(0).toLatin1())) }
        );
    }
}
有点难看,但能起作用

  • 无耦合类
  • 没有中间连接器功能

是否可以为
src
对象创建一个包含所需函数的类?
class SignalClass{
signals:
    void testSignal(QString tString);
};

class SlotClass{
public slots:
    void testSlot(char tChar);
};

class ConnectorClass{
public:
    void connectSignalAndSlot () {
        SignalClass tSigClass;
        SlotClass tSlotClass;
        connect(&tSigClass, &SignalClass::testSignal,
                [=](QString tString) { this->metaObject()->invokeMethod(tSlotClass,"testSlot", Q_ARG(char, tString.at(0).toLatin1())) }
        );
    }
}