zoukankan      html  css  js  c++  java
  • C++实现Qt的信号与槽

     一、使用C++11

    封装类

    // Connect.hpp
    #ifndef _CONNECT_H
    #define _CONNECT_H
    
    #include <vector>
    #include <memory>
    #include <functional>
    
    #define emit
    #define slots
    #define signals public
    #define connect(sender, signal, slot) ((sender)->signal.bind(slot))
    
    template<typename... Args>
    class Slot
    {
    public:
        using OnFunc = std::function<void(Args&&...)>;
    
        Slot(const OnFunc& func)
            : m_func(func)
        {
            // Do nothing
        }
    
        void exec(Args&&... args)
        {
            m_func(std::forward<Args>(args)...);
        }
    
    private:
        OnFunc m_func = nullptr;
    };
    
    template<typename... Args>
    class Signal
    {
    public:
        using SlotPtr = std::shared_ptr<Slot<Args&&...>>; 
        using OnFunc = std::function<void(Args&&...)>;
    
        void bind(const OnFunc& func)
        {
            m_slotVec.push_back(SlotPtr(new Slot<Args&&...>(func)));
        }
    
        void operator()(Args&&... args)
        {
            for (auto& iter : m_slotVec)
            {
                iter->exec(std::forward<Args>(args)...);
            }
        }
    
    private:
        std::vector<SlotPtr> m_slotVec;
    };
    
    #endif

    使用

    // main.cpp
    /************************************************
     * 该例程讲解用C++11来实现Qt的信号槽机制
     * 使用到的C++11特性有:
     * 1.可变参数模板类
     * 2.智能指针
     * 3.函数相关std::function、std::bind
     * 4.using关键字
     * 5.完美转发std::forward
    ************************************************/
    #include "Connect.hpp"
    #include <iostream>
    #include <string>
    
    class A
    {
    public:
        void start()
        {
            emit m_s1();
            emit m_s2("Hello C++11");
            emit m_s3(100, "Hello C++11");
        }
    
    signals:
        Signal<> m_s1;  // 不带参数的信号
        Signal<std::string> m_s2;
        Signal<int, std::string> m_s3;
    };
    
    class B
    {
    public slots:
        void func1()
        {
            std::cout << "func1" << std::endl;
        }
    
        void func2(const std::string& str)
        {
            std::cout << str << std::endl;
        }
    
        void func3(int n, const std::string& str)
        {
            std::cout << n << " " << str << std::endl;
        }
    };
    
    void func(const std::string& str)
    {
        std::cout << "func " << str << std::endl;
    }
    
    int main()
    {
        A a;
        B b;
    
        // 信号与槽绑定
        connect(&a, m_s1, std::bind(&B::func1, &b));
        connect(&a, m_s2, std::bind(&B::func2, &b, std::placeholders::_1));
        connect(&a, m_s3, std::bind(&B::func3, &b, std::placeholders::_1, std::placeholders::_2));
        connect(&a, m_s2, std::bind(func, std::placeholders::_1));
        connect(&a, m_s2, [](const std::string& str)
                {
                    std::cout << "lambda str: " << str << std::endl;
                });
    
        a.start();
    
        return 0;
    }

    转自:https://www.cnblogs.com/highway-9/p/5559558.html

    还没看懂....




    长风破浪会有时,直挂云帆济沧海!
    可通过下方链接找到博主
    https://www.cnblogs.com/judes/p/10875138.html
  • 相关阅读:
    面试题:找出数组中只出现一次的2个数(异或的巧妙应用)(出现3次)
    线段树 | 第1讲 (给定区间求和)(转)
    C++中的静态多态和动态多态(转)
    ARP与RARP详细解析(转)
    排序算法之归并排序
    byte数组使用Arrays.asList转换List出错
    排序算法之希尔排序
    排序算法之冒泡排序、选择排序、插入排序
    Tomcat配置优化
    内连接、左外连接、右外连接、全外连接、交叉连接
  • 原文地址:https://www.cnblogs.com/judes/p/15129082.html
Copyright © 2011-2022 走看看