Qt信号(SINGAL)与槽(SLOT)

Qt信号与槽原理

Qt之emit、singals、slot的使用

connect

信号槽是Qt对象间通讯的方法,主要通过connect()函数连接信号函数和槽函数进行通讯,就是将两个类关联起来
connect() 是QObject类的一个函数,有以下几种实现方式:

// 静态函数,连接SIGNAL(MySignal()),SLOT(MySlot())
// sender:表示需要发射信号的对象
// signal:表示发射的信号,该参数必须使用SIGNAL()
// receiver:表示需要接受信号的对象
// member:表示与信号关联的槽函数,这个参数也可以是信号,从而实现信号与信号的关联,如果是槽函数需要用SLOT()
static QMetaObject::Connection connect(const QObject *sender, const char *signal,
            const QObject *receiver, const char *member, Qt::ConnectionType = Qt::AutoConnection);

// 内联函数通过this->connect()的方式调用,接收者是this
inline QMetaObject::Connection connect(const QObject *sender, const char *signal,
            const char *member, Qt::ConnectionType type = Qt::AutoConnection) const;

// 内联静态函数,可以连接函数指针
template <typename Func1, typename Func2>
static inline typename std::enable_if<int(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0, QMetaObject::Connection>::type
            connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot);
// 内联静态函数,可以连接仿函数(lambda)
template <typename Func1, typename Func2>
static inline typename std::enable_if<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::type
            connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot);

// 除过以上几种,还有其他connect重载,此处不再描述

自定义信号与槽

常见错误处理方法

Qt自定义信号与槽示例
// mockQt.h
#include <QObject>

class MockQt :
    public QObject
{
    Q_OBJECT;

public:
    MockQt();
    ~MockQt() = default;

    //信号声明区
signals:
    void MySignal();
    void MySignal(int i);
    void MySignal(int m, int n);

    //槽函数声明区
private slots:
    void MySlot();
    void MySlot(int n);
    void MySlot(int m, int n);

public:
    void TestFunc(int i);
};

//mockQt.cpp
#include "mockQt.h"
#include <iostream>

MockQt::MockQt() {
    // 信号与槽函数连接
    connect(this, SIGNAL(MySignal()), SLOT(MySlot()));
    connect(this, SIGNAL(MySignal(int)), this, SLOT(MySlot(int))); //receive如果是this可写可不写
    connect(this, SIGNAL(MySignal(int, int)), SLOT(MySlot(int, int)));
}

void MockQt::MySlot() {
    std::cout << "mySlot()\n";
}
void MockQt::MySlot(int n) {
    std::cout << "mySlot(int n)\tn = " << n << '\n';
}
void MockQt::MySlot(int m, int n) {
    std::cout << "mySlot(int m,int n)\tm = " << m << "\tn = " << n << '\n';
}

void MockQt::TestFunc(int i) {
    switch (i)
    {
    case 0:
        emit MySignal(); // 发射信号
        break;
    case 1:
        emit MySignal(99);
        break;
    case 2:
        emit MySignal(88, 77);
        break;
    default:
        break;
    }
}

// main.cpp
#include "mockQt.h"

int main()
{
    MockQt mock;
    mock.TestFunc(0);
    mock.TestFunc(1);
    mock.TestFunc(2);

    return 0;
}
posted @ 2021-03-26 13:17  滴哒哒哒  阅读(327)  评论(0编辑  收藏  举报