QT信号与槽实现方式
1、第一种实现方式
在QT开发工具UI界面先拖入按钮,然后鼠标右键拖入按钮,点击选中槽,在页面选着需要的信号,然后OK,随即将会跳转到类的.cpp文件,(这种UI+代码结合的方式,会自动去绑定信号与槽)。
2、第二种实现方法
纯代码实现
2.1、在类的构造文件中绑定信号与槽
QObject::connect(sender,SIGNAL(signal()),receiver, SLOT(slot()));
sender------发送信号的对象
SIGNAL(signal())--------信号类型
receiver-------接收者
SLOT(slot())--------槽函数
2.2、类.h头文件声明槽函数
2.3、槽函数执行功能
2.4、报错解决
出现QObject::connect: Parentheses expected,这个错是我自己粗心,但也不得不吐槽下qt的不合理设计,connect时槽函数忘记加括号也可以编译通过,而且connect忘记加括号的槽函数是可以接收到信号的,因为我的槽函数里面打印的东西确实有输出。有点坑。
在类中使用信号/槽时一定要加Q_OBJECT宏,signal和slots的参数要一样
槽函数加(): connect(toTopLayerAction, SIGNAL(triggered()), this, SLOT(slotLayerTop())); // 正确
切记忘了():connect(toTopLayerAction, SIGNAL(triggered()), this, SLOT(slotLayerTop)); // 错误
3、第三种实现方法
3.1、使用Lambda表达式在构造函数中实现
QObject::connect(sender,&Sender::signal, [=]() {/* lambda body */ });
4、第四种方式
Qt 5中引入,允许使用函数指针直接 连接信号和槽,这种方式类型安全, 且可以利用IDE
的代码补全和错误检 查。
QObject::connect(sender,&Sender::signal, receiver,&Receiver::slot);
4.1、在构造函数中实现
5、自定义信号与槽
在Qt
中,自定义信号与槽是实现对象间通信的一种机制。信号和槽是
Qt
对象通信的核心特性,使得一个 对象能够在发生某种事件时通知其他对象。自定义信号与槽的实现步骤如下:
1. 定义信号
:在
Qt
中,信号是由
signals
关键字声明的类成员函数。它们不需要实现,只需声明。例
如:
class MyClass : public QObject {
Q_OBJECT
public:
MyClass();
signals:
void mySignal(int value);
};
在上面的例子中,
MyClass
有一个名为
mySignal
的信号,它带有一个整型参数。
定义槽:槽可以是任何普通的成员函数,但通常在类定义中用
slots
关键字标识。槽
可以有返回类型, 也可以接受参数,但它们的参数类型需要与发出信号的参数类型匹配
。例如:
class MyClass : public QObject {
Q_OBJECT
public slots:
void mySlot(int value);
};
在这个例子中,我们定义了一个名为
mySlot
的槽,它接收一个整型参数。
连接信号与槽:使用
QObject::connect
函数将信号与槽连接起来。当信号被发射时,连接到这个信号 的槽将被调用。
MyClass *myObject = new MyClass();
connect(myObject, SIGNAL(mySignal(int)), myObject, SLOT(mySlot(int)));
这行代码连接了
myObject
的
mySignal
信号到同一个对象的
mySlot
槽。
发射信号:使用
emit
关键字发射信号。当信号被发射时,所有连接到这个信号的槽都会被调用。
emit mySignal(123);
这将触发所有连接到
mySignal
的槽。
5.1、例1
#include "widget.h"
#include "ui_widget.h"
//widget.cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//连接槽 ,触发对象和接收都是自己
QObject::connect(this ,SIGNAL(mysignal()) ,this ,SLOT(myslot()));
QObject::connect( this ,SIGNAL(mysignalparams(int)) ,this ,SLOT(myslotparams(int)) );
emit mysignal(); //触发信号
emit mysignalparams(999); //触发带参数的信号
}
Widget::~Widget()
{
delete ui;
}
void Widget::myslot() //槽函数
{
std::cout << "myslot" << std::endl;
}
void Widget::myslotparams(int value)
{
std::cout << "myslotparams ," << value << std::endl;
qDebug() << "This is value = " << value;
}
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <iostream>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
signals: //自定义信号
void mysignal();
void mysignalparams(int value);
public slots: //自定义槽
void myslot();
void myslotparams(int value);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
执行结果
5.2、例2
创建两个类,比如Sender
和Receiver
。Sender
类将发出信号,而Receiver
类将接收并处理这个信号。
// Sender.h
#ifndef SENDER_H
#define SENDER_H
#include <QObject>
class Sender : public QObject {
Q_OBJECT
public:
explicit Sender(QObject *parent = nullptr);
signals:
void mySignal(); //信号
public slots:
void emitSignal();
};
#endif // SENDER_H
// Sender.cpp
#include "Sender.h"
Sender::Sender(QObject *parent) : QObject(parent) {
}
void Sender::emitSignal() {
emit mySignal(); //发送信号
}
// Receiver.h
#ifndef RECEIVER_H
#define RECEIVER_H
#include <QObject>
#include <QDebug>
class Receiver : public QObject {
Q_OBJECT
public:
explicit Receiver(QObject *parent = nullptr);
public slots:
void handleSignal(); //槽函数
};
#endif // RECEIVER_H
// Receiver.cpp
#include "Receiver.h"
Receiver::Receiver(QObject *parent) : QObject(parent) {
}
void Receiver::handleSignal() {
qDebug() << "Signal received!"; //槽函数
}
// main.cpp
#include <QCoreApplication>
#include "Sender.h"
#include "Receiver.h"
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
Sender sender;
Receiver receiver;
//连接信号与槽
QObject::connect(&sender, &Sender::mySignal, &receiver, &Receiver::handleSignal);
sender.emitSignal(); // 调用函数发送信号
return a.exec();
}
6、QDebug()
QDebug 是
Qt
框架中用于输出调试信息的一个类。它提供了一种方便的方式来输出文本到标准输出(通 常是控制台),这对于调试 Qt
应用程序非常有用。
QDebug
类可以与
Qt
的信号和槽机制一起使用,使 得在响应各种事件时能够输出有用的调试信息。
使用 QDebug
的一个典型方式是通过
qDebug()
函数,它返回一个
QDebug
对象。然后,可以使用流操 作符 <<
来输出各种数据类型。例如:
qDebug() << "This is a debug message";
int value = 10;
qDebug() << "The value is" << value;
当执行这些代码时,它们会在应用程序的控制台输出相应的文本。这对于检查程序的运行状态、变量的 值或者跟踪程序的执行流程非常有帮助。
还可以使用 qDebug()
来输出自定义类型,只要为这些类型提供了适当的输出操作符重载。此外,
Qt
还 提供了 qInfo()
, qWarning() , qCritical() 和 qFatal()
函数,用于输出不同级别的信息,分别用 于普通信息、警告、关键错误和致命错误。这有助于对日志信息进行级别划分,从而更好地控制输出内
容。