信号槽介绍
信号槽是Qt重要的一种机制, 这使得对象之间的通信非常方便。但是使用过程中会遇到连接失败的情况,下面就说一下信号槽的连接:
信号槽连接的前提条件:
1.信号有声明定义,Q_SIGNALS 有该关键字。
2.槽函数有声明定义以及实现, 有Q_SLOTS关键字, (QT5之后的版本普通函数也可以做槽函数)。
3.槽函数和信号声明的变量和类型一致。
4.自定义类要有Q_OBJECT关键字声明
这四个条件缺一不可。如果不满足,信号槽肯定会连接失败
示例代码
test.h
#inlcude <QDialog>
#include <QPushButton>
class test :public QDialog
{
public:explicit test(QDialog* parent= nullptr);
public Q_SLOTS:void btn_slot();
private:QPushButton* m_btn;
}
test.cpp
#include "test.h"
#include <QDebug>
test::test(QWidget* parent):
QDialog(parent),
m_btn(new QPushButton(this)){if(!connect(m_btn, SIGNAL(clicked()), this,SLOT(btn_slot()))){Q_ASSERT(false);}
}
void test::btn_slot()
{qDebug()<<"btn is clicked";
}
这个例子中信号和槽连接是失败的。你会发现, 信号,槽都有, 信号和槽参数也都一致,怎么就连接失败了,编译也没有报错.
仔细看会发现这是一个自定义的类,由于类中没有声明Q_OBJECT该关键字, 该文件就不会生成对应的moc文件, 也就无法建立QObject中的信号槽机制。
修改点:
将test.h文件个改成下面即可
#inlcude <QDialog>
#include <QPushButton>
class test :public QDialog
{
Q_OBJECT
public:explicit test(QDialog* parent= nullptr);
public Q_SLOTS:void btn_slot();
private:QPushButton* m_btn;
}
新建文件很容易忘记添加Q_OBJECT该关键字。导致信号槽连接失败。由于又没有明显的编译提示,不仔细看的话容易忽略这个点。