前天在我很久以前的一篇博文
(http://blog.csdn.net/liukang325/article/details/45742675)
中有人回復說看到我的博文很激動,希望我詳細介紹一下信號與槽的機制,想自己通過回調實現一下。我寫的博客能幫助到你我也很激動!~所以就依我自己的理解簡單實現一下供你參考~
只是一個最簡單的信號。並沒有實現 QT中信號還帶參數傳遞的功能。想要更深入的理解,可以閱讀一下QT的源碼。
大家知道想要用Qt中的信號槽。離不開QObject,那么我就寫個最簡單的KObject
KObject.h
#include <map>
# define kslots
# define ksignals public
# define kemit
class KObject;
struct MetaObject
{
static void active(KObject * sender, int idx);
};
struct Connection
{
KObject * receiver;
int sltID;
};
typedef std::map<int, Connection> ConnectionMap;
class KObject
{
friend class MetaObject;
static MetaObject meta;
public:
KObject();
virtual ~KObject();
static void kconnect(KObject*, int, KObject*, int);
protected:
virtual void metacall(int sltID) = 0;
ksignals:
//void sigtest();
public kslots:
//void slottest();
private:
ConnectionMap connections;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
KObject.cpp
#include "KObject.h"
void MetaObject::active(KObject* sender, int sigID)
{
Connection c = sender->connections[sigID];
c.receiver->metacall(c.sltID);
}
KObject::KObject(){}
KObject::~KObject(){}
void KObject::kconnect(KObject* sender, int sigID, KObject* receiver, int sltID)
{
Connection c = {receiver, sltID};
sender->connections.insert(std::pair<int, Connection>(sigID, c));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
接下來寫兩個測試的類,繼承於KObject
TestClassA.h
#include "KObject.h"
class TestClassA : public KObject
{
public:
TestClassA();
protected:
void metacall(int sltID);
ksignals:
typedef enum{
SIG_HELLOWORLD,
}SIG_ID;
void sigTestA(int sigID);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
TestClassA.cpp
#include "TestClassA.h"
TestClassA::TestClassA()
{
}
void TestClassA::metacall(int sltID)
{
}
void TestClassA::sigTestA(int sigID)
{
MetaObject::active(this, sigID);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
TestClassB.h
#include "KObject.h"
class TestClassB : public KObject
{
public:
TestClassB();
void metacall(int sltID);
public kslots:
typedef enum{
SLT_HELLOWORLD = 2,
}SLT_ID;
void slotTestB();
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
TestClassB.cpp
#include "TestClassB.h"
TestClassB::TestClassB()
{
}
void TestClassB::metacall(int sltID)
{
switch (sltID) {
case SLT_HELLOWORLD:
slotTestB();
break;
default:
break;
};
}
void TestClassB::slotTestB()
{
QDBG << "hello world TestB";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
最后寫main函數
TestClassA a;
TestClassB b;
KObject::kconnect(&a, TestClassA::SIG_HELLOWORLD, &b, TestClassB::SLT_HELLOWORLD);
a.sigTestA(TestClassA::SIG_HELLOWORLD);
1
2
3
4
調用的是a.sigTestA(TestClassA::SIG_HELLOWORLD);
會打印TestClassB::slotTestB()中的”hello world TestB”;
以上三個類所有的代碼不過百來行,實現的是最基本最簡單的一個類信號觸發另一個類的槽函數。這里信號只是一個ID,沒有像QT中那樣豐富的實現信號函數,還帶有多種參數傳遞,以及多種connect的寫法。
這個例子只是方便你很簡單的理解兩個類之間信號與槽是怎么傳遞的。
希望對你有幫助~
轉載請注明來源:http://blog.csdn.net/liukang325/article/details/78151601
---------------------
作者:陽光檸檬_
來源:CSDN
原文:https://blog.csdn.net/liukang325/article/details/78151601
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!