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

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

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

我该如何实现这样的组合?
5个回答

39

根据信号槽文档

信号的签名必须与接收槽的签名相匹配。(实际上,槽可以比它接收的信号具有更短的签名,因为它可以忽略额外的参数。)

这意味着形式为

signal(int, int, QString)

的信号只能连接到以下签名的槽:

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

正如koan建议的那样,最好的方法是使用另一个带有QString参数的slot,然后调用你实际想要的slot。


能否为src对象创建一个类,并在其中添加所需的函数? - chwi

22

一种简单的方法是使用一个中间槽口调用您想要的槽口,例如:

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

然后

void receiveLink(QString blah)
{
  int response = someFunction(blah);
  mybutton->call(response);
}

你需要定义一种将字符串解释为整数的方法。


5

默认值对于插槽参数非常有帮助。这样可以将具有不同信号签名的信号连接到插槽中(反之亦然,参见 @pnezis 的答案):

private slots:
  void slot( int x = 10, int y = 20, QString text = QString() );

可能连接到不同的信号:

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

此外,Qt 4.8还提供了有用的QSignalMapper类:

该类收集一组无参数信号,并使用整数、字符串或窗口小部件参数重新发出它们,这些参数对应于发送信号的对象。

但只适用于一个参数:

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 &)));

0
作为补充答案,如果您不想编写中间插槽,可以使用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())) }
        );
    }
}

代码看起来有点丑,但是能够完成任务。

  • 没有耦合的类
  • 没有中间连接函数

0

一种更现代的解决方案是使用qOverload

struct Foo {
        void overloadedFunction(int, const QString &);
        void overloadedFunction(int, const QString &) const;
    };
    ... qConstOverload<int, const QString &>(&Foo::overloadedFunction)
    ... qNonConstOverload<int, const QString &>(&Foo::overloadedFunction)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接