我的信号/插槽连接不起作用

硅法师

我一再看到有人遇到无法调用插槽的问题。我想收集一些最常见的原因。因此,也许我可以为人们提供帮助,避免很多重复的问题。

信号/插槽连接不起作用的原因是什么?如何避免此类问题?

硅法师

有一些规则可以简化信号和插槽的使用寿命,并涵盖连接不良的最常见原因。如果我忘记了什么,请告诉我。

1)检查调试控制台输出:

当发生执行错误时,调试输出可以为您显示原因。

2)使用信号和插槽的完整签名:

代替

connect(that, SIGNAL(mySignal), this, SLOT(mySlot));

connect(that, SIGNAL(mySignal(int)), this, SLOT(mySlot(int)));

并检查您的拼写和大写。

3)使用现有的重载:

仔细检查您是否正在使用所需的信号和插槽过载,以及您实际使用的过载是否存在。

4)您的信号和插槽必须兼容:

这尤其意味着参数必须具有相同的类型(允许引用)并且具有相同的顺序。

编译时语法也需要相同数量的参数。旧的运行时语法允许使用较少的参数将信号连接到插槽。

5)始终检查connect方法的返回值(程序员切勿忽略返回值):

代替

connect(that, SIGNAL(mySignal(int)), this, SLOT(mySlot(int)));

总是使用类似

bool success = connect(that, SIGNAL(mySignal(int)), this, SLOT(mySlot(int)));
Q_ASSERT(success);

或者,如果您喜欢引发异常或实施完整的错误处理。您也可以使用这样的宏:

#ifndef QT_NO_DEBUG
#define CHECK_TRUE(instruction) Q_ASSERT(instruction)
#else
#define CHECK_TRUE(instruction) (instruction)
#endif 

CHECK_TRUE(connect(that, SIGNAL(mySignal(int)), this, SLOT(mySlot(int))));

6)您需要一个事件循环来排队连接:

即,当您连接不同线程拥有的两个对象的信号/插槽(所谓的排队连接)时,您需要exec();在插槽的线程中调用

事件循环也需要实际服务。只要插槽的线程陷入某种繁忙的循环中,就不会执行排队的连接!

7)您需要为队列连接注册自定义类型:

因此,在队列连接中使用自定义类型时,您必须为此注册它们。

首先使用以下宏声明类型:

Q_DECLARE_METATYPE(MyType)

然后使用以下调用之一:

qRegisterMetaType<MyTypedefType>("MyTypedefType"); // For typedef defined types
qRegisterMetaType<MyType>(); // For other types

8)优先使用新的编译时语法而不是旧的运行时检查语法:

代替

connect(that, SIGNAL(mySignal(int)), this, SLOT(mySlot(int)));

使用此语法

connect(that, &ThatObject::mySignal, this, &ThisObject::mySlot));

它在编译时检查信号和插槽,甚至不需要将目标作为实际插槽。

如果信号过载,请使用以下语法:

connect(that, static_cast<void (ThatObject::*)(int)> &ThatObject::mySignal), this, &ThisObject::mySlot); // <Qt5.7
connect(that, qOverload<int>::of(&ThatObject::mySignal), this, &ThisObject::mySlot); // >=Qt5.7 & C++11
connect(that, qOverload<int>(&ThatObject::mySignal), this, &ThisObject::mySlot); // >=Qt5.7 & C++14

从Qt5.14开始,不赞成使用过载信号。禁用不推荐使用的Qt功能以摆脱上述欺骗。

也不要为该语法混合使用const / non-const信号/插槽(通常,信号和插槽将是非const)。

9)您的类需要一个Q_OBJECT宏:

在使用“信号”和“插槽”规范的类中,您需要添加Q_OBJECT宏,如下所示:

class SomeClass
{
   Q_OBJECT

signals:
   void MySignal(int x);
};

class SomeMoreClass
{
   Q_OBJECT

public slots:
   void MySlot(int x);
};

该宏将必要的元信息添加到类中。

10)您的对象必须是活的:

一旦发送方对象或接收方对象被破坏,Qt就会自动丢弃该连接。

如果未发出信号:发送方对象是否仍然存在?如果未调用该插槽:接收器对象是否仍然存在?

要检查两个对象的寿命,请使用调试器断点或构造函数/析构函数中的某些qDebug()输出。

11)它仍然不起作用:

要对连接进行非常快速和肮脏的检查,请使用一些伪参数自行发出信号,然后查看是否被调用:

connect(that, SIGNAL(mySignal(int)), this, SLOT(mySlot(int)));
emit that->mySignal(0); // Ugly, don't forget to remove it immediately

最后当然当然有可能根本不发出信号。如果遵循上述规则,则程序逻辑中可能出了一些问题。阅读文档。使用调试器。如果现在还有其他方法,请向stackoverflow询问。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

连接信号和插槽不起作用 Qt

来自分类Dev

PyQt5:所连接的插槽与单击信号不起作用

来自分类Dev

Qt信号/插槽不起作用[非常基本]

来自分类Dev

QT- 信号和插槽 setEnabled(bool) 插槽不起作用

来自分类Dev

插槽 setShowGride 在我的应用程序中不起作用

来自分类Dev

信号与功能之间的PyQt程序连接不起作用

来自分类Dev

如果从QRunnable或其他线程调用Qt信号和插槽,则它们不起作用

来自分类Dev

自定义类中的信号和插槽(包括PyQt QWidget)不起作用

来自分类Dev

为什么这个PyQt5 Qlistwidget信号+插槽不起作用?

来自分类Dev

QT5 C++ 信号到 QML 插槽不起作用

来自分类Dev

我的USB插槽之一不起作用,但其他USB插槽很好

来自分类Dev

为什么我的信号处理程序不起作用?

来自分类Dev

为什么我的信号处理程序不起作用?

来自分类Dev

Django信号不起作用

来自分类Dev

pthread信号不起作用

来自分类Dev

QDialog :: accepted()插槽不起作用

来自分类Dev

QDialog :: accepted()插槽不起作用

来自分类Dev

连接不起作用

来自分类Dev

为什么我的连接字符串不起作用?

来自分类Dev

django-信号不起作用

来自分类Dev

django信号断开不起作用

来自分类Dev

信号灯不起作用C ++

来自分类Dev

QMessageBox 的 buttonClicked 信号不起作用

来自分类Dev

jsplumb连接不起作用

来自分类Dev

Netty 连接不起作用

来自分类Dev

pthread和信号量在osx maverick 10.9中对我不起作用

来自分类Dev

右键菜单上的插槽操作不起作用

来自分类Dev

Qt C ++自定义插槽不起作用

来自分类Dev

Qt:自定义插槽不起作用