QT学习笔记之信号槽

QT信号槽

学习和使用QT,信号槽是必须掌握的一个知识点。

概念

signal,信号,扮演生产者/触发器这样的角色
slot,槽,扮演消费者/响应器这样的角色

槽作为信号的观察者而存在,在设计结构上属于“观察者模式”

关系

  • 通过QObject::connect函数建立一个信号和一个槽的连接关系;
  • 同一个信号可以绑定给任意个槽(0, 1, 2, …),信号触发后,所有绑定的槽会按照connect执行顺序依次被调用触发;

特征

  • 使用"emit signalFunction();"这样的方式“发射信号”,发射信号的操作是无阻塞的,类似于Windows的PostMessage;
  • 信号函数只需要声明,不需要实现——其作用主要是作为具体某种信号的名称(class_function
  • 信号函数和槽函数的参数必须保持一致,信号函数的参数列表会传递给槽函数

连接函数

我们直接看qobject.h的源代码

// Connect a signal to a pointer to qobject member function
// connect: 创建信号和槽的绑定关系的函数
// [参数] sender   信号类对象指针
// [参数] signal   信号函数--信号类的成员函数,带signals宏声明
// [参数] receiver 槽类对象指针
// [参数] slot     槽函数--槽类的成员函数,带slot宏声明
template <typename Func1, typename Func2>
static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot, Qt::ConnectionType type = Qt::AutoConnection)
{
      typedef QtPrivate::FunctionPointer<Func1> SignalType;
      typedef QtPrivate::FunctionPointer<Func2> SlotType;

	  // 断言:signal函数,所属的class里面必须有Q_OBJECT宏
      static_assert(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
                        "No Q_OBJECT in the class with the signal");

      //compilation error if the arguments does not match.
      // 断言:signal函数的参数数量 >= slot函数的参数数量
      static_assert(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
                        "The slot requires more arguments than the signal provides.");
      // 断言:signal函数和slot函数的参数类型必须按顺序保持一致
      static_assert((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
                        "Signal and slot arguments are not compatible.");
      // 断言:signal函数和slot函数的返回值类型必须相同
      static_assert((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
                        "Return type of the slot is not compatible with the return type of the signal.");

      const int *types = nullptr;
      if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
          types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();

      return connectImpl(sender, reinterpret_cast<void **>(&signal),
                         receiver, reinterpret_cast<void **>(&slot),
                         new QtPrivate::QSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
                                         typename SignalType::ReturnType>(slot),
                          type, types, &SignalType::Object::staticMetaObject);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值