signal & slot

别来无恙 提交于 2020-03-07 06:06:23

The Qt signals/slots and property system are based on the ability to introspect the objects at runtime.
C++ does not offer introspection support natively, so Qt comes with a tool to provide it. That tool is MOC.
It parses the header files and generates an additional C++ file that is compiled with the rest of the program
  (1) signals, slots fucntion are simple functions, but MOC will see them
  (2) Q_OBJECT defines a bunch of functions and a static QMetaObject, all signals/connections are stored here

we can get the deatails about it from https://woboq.com/blog/how-qt-signals-slots-work.html

write one very simple and similar example that implements signala and slot:

 

// file :QObject.h
#include<map>
#define SIGNAL int
#define SLOT void
#define CONNECT(ObjectA,signal,ObjectB,slot) ObjectA.getMeta()->connection.insert(std::pair<int,void*>(signal,(void*)new Caller(ObjectB,slot)))
#define EMIT(ObjectA,signal) ObjectA.activate(signal)

class Caller
{
public:
    class icaller{ public:virtual void run() = 0; };
    template<class T>
    class caller :public icaller {
    public:
        caller(T * obj, void(T::*call)()) :object(obj), func(call){}
        virtual void run(){ (object->*func)(); }
        T * object;
        void(T::*func)();
    };
    template<class T>
    Caller(T*object, void (T::*clk)()){ p = new caller<T>(object, clk); }
    icaller * p;
    void run() { p->run(); }
};

struct QmetaObject
{
    std::map<int, void*> connection;
};

class QObject
{
public:
    QmetaObject * getMeta(){ return &metadata; }
    // we can create a new thread, queue the caller
    void activate(int sig){ Caller * pfunc = (Caller*)getMeta()->connection.at(sig); pfunc->run(); }
private:
    // metadata
    QmetaObject metadata;
};

 

the functionality of class Caller see here:http://www.cnblogs.com/resibe-3/p/6639151.html

#include"QObject.h"
#include<iostream>
class myclassA : public QObject{
public:
    myclassA() :A(1){}
    SIGNAL A;
};

class myclassB : public QObject{
public:
    SLOT B(){ std::cout << " function B was called" << std::endl;}
};

void callback(){ myclassB bb; bb.B(); }
void pushbutton(myclassA aa){
    // suppose we push an button aa, 
    // if we adopt signal-slot mechanism, it will emit a signal here
    EMIT(aa, aa.A);
    // if we use callback,then
    // callback();
}

int main()
{
    myclassA aa;
    myclassB bb;
    CONNECT(aa, aa.A, &bb, &myclassB::B);
    pushbutton(aa);
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!