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
  • 相关阅读:
    'jar' 不是内部或外部命令,也不是可运行的程序 或批处理文件。或批处理文件
    idea 集成 javap
    JVM_ 动态链接
    远程服务调用RMI框架 演示,和底层原理解析
    IO/NIO/AIO 解读
    JUC 并发编程--10, 阻塞队列之--LinkedBlockingDeque 工作窃取, 代码演示
    github,使用技巧, 让你的开发事半功倍
    JVM-相关,这里引用别人博客
    python开发学习day01 (编程; 计算机三大核心硬件 ; 操作系统与平台)
    webdriervAPI(多表单切换)
  • 原文地址:https://www.cnblogs.com/judes/p/15129082.html
Copyright © 2011-2022 走看看