• QT 信号与槽connect


    QT 信号与槽connect

    QT中信号与槽的连接使用的connect函数是一个静态函数,在类QObject中定义。这里说的是QT5环境下。更详细的介绍可以看这里http://www.devbean.net/2012/12/how-qt-signals-and-slots-work-qt5/

    本文由乌合之众 lym瞎编,欢迎转载 blog.cnblogs.net/oloroso
    本文由乌合之众 lym瞎编,欢迎转载 my.oschina.net/oloroso

    connect函数调用几个限制

    • 1. 信号的发送者必须是QObject的派生类对象。不然会出现error: invalid conversion from 'XXX*' to 'const QObject*' [-fpermissive]...的错误。

    • 2. 回调槽函数的对象必须是QObject的派生类对象。不然会出现error: no matching function for call to 'QObject::connect(XXX*,的错误。这里要注意一点,信号函数无论存在与否,都不会报错的。但是如果信号的发送者是NULL,那么会在运行的时候提示QObject::connect: Cannot connect (null)::信号函数() to 接收者::槽函数()的问题。

    • 对于1,2两点,在connect函数调用的时候强转类型也可以通过编译,但是运行的时候会提示No such slot QObject::的问题。

    • 3. 槽函数所在的类的定义中必须添加宏Q_OBJECT,不然会出现QObject::connect: No such slot ...的错误。

      这里必须和第2点联系起来,如果添加了Q_OBJECT宏的类不是从QObject派生的,moc生成中间文件的时候会报错Error: Class contains Q_OBJECT macro but does not inherit from QObject

      如果添加了Q_OBJECT宏之后编译出现了undefined reference to ‘vtable for...的错误,请删除build目录下的Makefile文件,再重新生成。

    • 4. 信号函数的signals修饰和槽函数的slots修饰其实是必须的。虽然生成的中间代码中会去除掉。

    • 5.如果槽函数是on_控件名_信号名那么不需要主动调用connnect进行连接。
    问题原因
    error: no matching function for call to 'QObject::connect(XXX*, 信号的发送者和接受者必须是QObject的派生类对象。
    QObject::connect: No such slot ... 满足面的条件后,还必须满足槽函数所在类的定义中添加(使用)了Q_OBJECT
    Error: Class contains Q_OBJECT macro but does not inherit from QObject 添加了Q_OBJECT宏的类不是从QObject派生的
    undefined reference to ‘vtable for... 这是在添加了Q_OBJECT宏之后编译出现,原因是没有更新Makefile文件。请删除build目录下的Makefile文件,再使用qmake重新生成。
    No matching signal for on_XXXXX_XXXXX() 槽函数是on_控件名_信号名形式,又显示的调用了connect进行连接,就会在运行时出现这个,但是没有什么关系。

    connect函数代码

    connect是一个模板函数,但是对参数的类型是有要求的。
    这个函数的返回值是QMetaObject::Connection类型的。

     1 //Connect a signal to a pointer to qobject member function
     2 //连接一个信号到 qobject 成员函数的指针
     3 
     4 template <typename Func1, typename Func2>
     5 static inline QMetaObject::Connection connect(
     6     const typename QtPrivate::FunctionPointer<Func1>::Object *sender,
     7     Func1 signal,
     8     const typename QtPrivate::FunctionPointer<Func2>::Object *receiver,
     9     Func2 slot,Qt::ConnectionType type = Qt::AutoConnection
    10     )
    11 {
    12     typedef QtPrivate::FunctionPointer<Func1> SignalType;
    13     typedef QtPrivate::FunctionPointer<Func2> SlotType;
    14 
    15     //检查信号类是否有Q_OBJECT宏
    16     Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
    17                       "No Q_OBJECT in the class with the signal");
    18 
    19     //compilation error if the arguments does not match.
    20     //如果参数不匹配的编译错误。
    21     //槽函数需要的参数比信号函数提供多。
    22     Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
    23                       "The slot requires more arguments than the signal provides.");
    24     //信号函数和槽函数的参数不是兼容的。
    25     Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
    26                       "Signal and slot arguments are not compatible.");
    27     //信号函数返回类型是槽函数的不兼容的返回类型。
    28     Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
    29                       "Return type of the slot is not compatible with the return type of the signal.");
    30 
    31     const int *types = 0;
    32     if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
    33         types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
    34 
    35     //QObject::connectImpl是用于执行连接的私有内部函数。
    36     //槽函数的包装器,用于辅助调用该槽函数。
    37     return connectImpl(sender, reinterpret_cast<void **>(&signal),
    38                        receiver, reinterpret_cast<void **>(&slot),
    39                        new QtPrivate::QSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
    40                        typename SignalType::ReturnType>(slot),
    41                        type, types, &SignalType::Object::staticMetaObject);
    42 }
  • 相关阅读:
    .Net中的设计模式——Decorator模式
    PetShop的系统架构设计
    PetShop数据访问层之消息处理
    对象的封装与C#的类
    Flash/Flex学习笔记(46):正向运动学
    Flash/Flex学习笔记(43):动量守恒与能量守恒
    win7下恢复“经典任务栏”/“快速启动栏”,关闭“窗口自动最大化”
    Flash/Flex学习笔记(50):3D线条与填充
    图片的javascript延时加载
    Flash/Flex学习笔记(51):3维旋转与透视变换(PerspectiveProjection)
  • 原文地址:https://www.cnblogs.com/oloroso/p/4653770.html
Copyright © 2020-2023  润新知