【qt信号槽-3】(QObject::connect: No such slot)的一种解决方法,connect函数qt4/qt5格式,元数据注册

背景:

【qt信号槽-1】槽函数重写问题,qt_metacall和qt_static_metacall

【qt信号槽-2】Qt中窗体继承,槽响应多次执行的解决

【qt信号槽-3】(QObject::connect: No such slot)的一种解决方法,connect函数qt4/qt5格式,元数据注册

【qt信号槽-4】槽函数不响应不执行的一种原因:ui提升导致重名

【qt信号槽-5】信号槽相关注意事项记录

信号槽参数使用了自定义枚举,运行报错。先看代码:

class Exec_Multi_Sample : public Exec_Multi_Base
{
    Q_OBJECT
public:
    enum EState  {  ...  } m_eState;

private slots:
    void onSetState(EState e);

    ...
};
Q_DECLARE_METATYPE(Exec_Multi_Sample::EState)

自认为已经注意了相关事宜。但还是运行报错QObject::connect: No such slot。

解决:

在定义枚举的类当中,引用该枚举也要写全类名,像这样:

class Exec_Multi_Sample : public Exec_Multi_Base
{
    Q_OBJECT
public:
    enum EState  {  ...  } m_eState;

private slots:
    void onSetState(Exec_Multi_Sample::EState e);//就是这里

    ...
};
Q_DECLARE_METATYPE(Exec_Multi_Sample::EState)

当然,在实现文件.cpp里面也要这样写,然后就没问题了。

分析:

之前在各涉及到该信号槽的地方,除了槽函数的声明和定义,其它地方都写全了类名“Exec_Multi_Sample::”,当然connect也是如此。看来是qt没有足够智能解决这个问题。纵使再有什么原理,我个人认为,在类的内部,理论上类名应该可以省略。

追加(另一种解决方法):

关于connect函数的用法,之前我都是使用qt4的语法:

connect(sender, SIGNAL(mySignal(parameters)), receiver, SLOT(mySlot(parameters)));

最初的想法,一方面是习惯,另一方面可以很明确看到参数列表,当需要重载的时候就比较好用。信号槽没有参数时,这种写法比qt5格式简短。但缺点是,当查找信号或者槽的引用时,qt creator找不到connect这里。至少我尝试的情况是这样的。

后来全部改为qt5格式:

connect(sender, &senderClass::mySignal, receiver, &receiverClass::mySlot);

当信号槽没有参数时,因为有类名和双冒号,写出来太长。但优点是,在查找信号槽引用时,qt creator可以定位到connect这里。

之所以要提到connect格式,是改用qt5格式以后,之前“(QObject::connect: No such slot)”的问题貌似没有了。

另外涉及到元数据类型注册的问题,还要记录一下。

元数据注册:

Q_DECLARE_METATYPE():

亲测需要写在类外面,此时当然参数中需要写全类型名,加上类名和双冒号。

Q_ENUM:

手册说,需要类已经使用过 Q_OBJECT/Q_GADGET/Q_ENUM_NS(),我的理解是,继承在QObject的类使用它。亲测可以写在类里面,直接写在枚举定义的后面就行,不用写类名加双冒号。

qRegisterMetaType<MyClass>("MyClass"):

qRegisterMetaType<MyClass>():

自定义类型用于信号槽时,需要执行它。使用过Q_DECLARE_METATYPE/Q_ENUM的类型,用于信号槽时,需要执行它。

本文完。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: QObject::connect函数可以用来建立对象之间的信号的连接,可以使一个对象的信号触发另一个对象的函数。它的用法是:QObject::connect(sender, signal, receiver, slot)。 ### 回答2: QObject::connect函数Qt中用于建立信号连接的函数,它的语法如下: QObject::connect(sender, signal, receiver, slot, connectionType); 其中,sender是发送信号的对象,signal是发出的信号,receiver是接收信号的对象,slot是处理信号函数connectionType是一个可选参数,用于指定连接的类型,默认为Qt::AutoConnection。 使用QObject::connect函数,首先需要确定信号函数的声明,然后可以在程序的任意位置调用该函数进行连接。例如,假设有一个按钮对象button和一个函数slotFunction,可以使用以下代码连接信号: QObject::connect(button, SIGNAL(clicked()), this, SLOT(slotFunction())); 在这个例子中,当按钮被点击时,会触发一个clicked信号,然后会调用函数slotFunction来处理该信号。 连接时还可以使用lambda表达式来代替函数,例如: QObject::connect(button, &QPushButton::clicked, [](){ qDebug() << "Button clicked"; }); 这里使用了C++11的lambda表达式作为函数,当按钮被点击时,会输出一条调试信息。 需要注意的是,QObject::connect函数只能连接QObject或其子类的实例之间的信号,且函数必须是可调用的(可以是普通函数、成员函数、静态函数等)。 总结而言,QObject::connect函数Qt中用于建立信号连接的重要函数,它的使用需要理解信号的声明,并进行正确的参数传递。 ### 回答3: QObject::connect函数用于建立信号之间的连接,使得当信号触发时,函数会被自动调用。 函数的基本语法如下: connect(sender, signal, receiver, slot, Qt::ConnectionType); 其中,sender是发送信号的对象,signal是发送的信号,receiver是接收信号的对象,slot是接收信号调用的函数。 例子: 我们有一个名为button的QPushButton对象,我们想在用户点击按钮时触发一个名为myFunction的函数。 首先,我们需要在Qt头文件中声明和定义函数myFunction。 然后,在我们的代码中,我们可以连接按钮的clicked信号和myFunction函数,如下所示: QObject::connect(button, &QPushButton::clicked, this, &MyClass::myFunction); 在这个例子中,button是发送clicked信号的对象,&QPushButton::clicked表示clicked信号,this是接收信号的对象,&MyClass::myFunction表示myFunction函数。 最后一个参数Qt::ConnectionType是可选的,默认为Qt::AutoConnection,会根据发送和接收对象的线程自动选择信号的连接方式。你可以根据需要使用其他连接方式。 总结起来,QObject::connect函数简单地描述了信号之间的连接关系,使得当信号发出时,函数会被自动调用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值