????????Qt的信号与槽主要是为了对象之间的信号传递,以达到某种交互操作的功能。我按照自己的理解逐步实现这样的效果。
步骤一:
????????第一个类(接收者)的成员函数实现某种功能,第二个类(发送者)定义一个对象指针,初始化后达到间接访问类1(接收者)的成员函数。运行后显示:I am a receiver!
#include <iostream>
using namespace std;
class Receiver
{
public:
void show()
{
cout <<"I am a receiver!"<<endl;
}
};
class Transimiter
{
public:
Receiver * p_receiver;
};
int main()
{
Transimiter t1;
Receiver r1;
t1.p_receiver=&r1;
t1.p_receiver->show();
return 0;
}
步骤二:
? ? ? ? 不能把所有的事情都让类的成员函数去处理,因为没有人知道未来会添加哪些功能,所以把接收者中定义的show函数改成一个函数指针会更合理。这样可以在接收者初始化对象的时候赋予具体的函数地址,完成具体的功能。运行结果:
I am a slot_show function!
I am a slot_print function!
#include <iostream>
using namespace std;
class Receiver
{
public:
void (*fun)();//函数指针
Receiver(void (*pfun)())
{
this->fun=pfun;//函数指针初始化
}
};
void slot_show()
{
cout<<"I am a slot_show function!"<<endl;
}
void slot_print()
{
cout<<"I am a slot_print function!"<<endl;
}
class Transimiter
{
public:
Receiver * p_receiver;
};
int main()
{
Transimiter t1;
Receiver r1(&slot_show);//定义两个不同的接收者对象
Receiver r2(&slot_print);
t1.p_receiver=&r1;
t1.p_receiver->fun();
t1.p_receiver=&r2;
t1.p_receiver->fun();
return 0;
}
步骤三:
? ? ? ? 为了解决一个发送者对象和多个接收者对象产生关系的问题,发送者对象应该用一个指针数组保存所有的接收者,我的数组大小为2。程序的运行结果和上面一样。
#include <iostream>
using namespace std;
class Receiver
{
public:
void (*fun)();//函数指针
Receiver(void (*pfun)())
{
this->fun=pfun;//函数指针初始化
}
};
void slot_show()
{
cout<<"I am a slot_show function!"<<endl;
}
void slot_print()
{
cout<<"I am a slot_print function!"<<endl;
}
class Transimiter
{
public:
Receiver * p_receiver[2];
};
int main()
{
Transimiter t1;
Receiver r1(&slot_show);//定义两个不同的接收者对象
Receiver r2(&slot_print);
t1.p_receiver[0]=&r1;
t1.p_receiver[1]=&r2;
t1.p_receiver[0]->fun();
t1.p_receiver[1]->fun();
return 0;
}
步骤四:
? ? ? ?有关发送者对象的信号发送,应当有一个专门的成员函数集中处理,?所以程序做一点修正,运行结果不变,如下:
#include <iostream>
using namespace std;
class Receiver
{
public:
void (*fun)();//函数指针
Receiver(void (*pfun)())
{
this->fun=pfun;//函数指针初始化
}
};
void slot_show()
{
cout<<"I am a slot_show function!"<<endl;
}
void slot_print()
{
cout<<"I am a slot_print function!"<<endl;
}
class Transimiter
{
public:
Receiver * p_receiver[2];
public:
void send_message()
{
this->p_receiver[0]->fun();
this->p_receiver[1]->fun();
}
};
int main()
{
Transimiter t1;
Receiver r1(&slot_show);//定义两个不同的接收者对象
Receiver r2(&slot_print);
t1.p_receiver[0]=&r1;
t1.p_receiver[1]=&r2;
t1.send_message();
return 0;
}
步骤五:
? ? ? ? 上面的程序发送的消息是空的,我用一个整型的数字代表一个合法的消息,程序稍作修改,运行结果如下:
I am a slot_show function!
num:100
I am a slot_print function!?
num:100
#include <iostream>
using namespace std;
class Receiver
{
public:
void (*fun)(int);//函数指针
Receiver(void (*pfun)(int))
{
this->fun=pfun;//函数指针初始化
}
};
void slot_show(int num)
{
cout<<"I am a slot_show function!"<<endl;
cout<<"num:"<<num<<endl;
}
void slot_print(int num)
{
cout<<"I am a slot_print function!"<endl;
cout<<"num:"<<num<<endl;
}
class Transimiter
{
public:
Receiver * p_receiver[2];
public:
void send_message(int num)
{
this->p_receiver[0]->fun(num);
this->p_receiver[1]->fun(num);
}
};
int main()
{
Transimiter t1;
Receiver r1(&slot_show);//定义两个不同的接收者对象
Receiver r2(&slot_print);
t1.p_receiver[0]=&r1;
t1.p_receiver[1]=&r2;
t1.send_message(100);
return 0;
}
步骤六:
? ? ? ? 上面的程序中发送者和接收者之间建立联系的过程不够形象,我用一个函数命名为管道连接,管理对象之间的通信管道。安全起见,同时把发送者对象里面的指针数组从公用属性改为私有属性。
#include <iostream>
using namespace std;
class Receiver
{
public:
void (*fun)(int);//函数指针
Receiver(void (*pfun)(int))
{
this->fun=pfun;//函数指针初始化
}
};
void slot_show(int num)
{
cout<<"I am a slot_show function!"<<endl;
cout<<"num:"<<num<<endl;
}
void slot_print(int num)
{
cout<<"I am a slot_print function!"<<endl;
cout<<"num:"<<num<<endl;
}
class Transimiter
{
private://成员变量改为私有属性
Receiver * p_receiver[2];
public:
void send_message(int num)
{
this->p_receiver[0]->fun(num);
this->p_receiver[1]->fun(num);
}
void connect_pipe(Receiver *pR,int num)//建立管道连接
{
this->p_receiver[num]=pR;
}
};
int main()
{
Transimiter t1;
Receiver r1(&slot_show);//定义两个不同的接收者对象
Receiver r2(&slot_print);
t1.connect_pipe(&r1,0);
t1.connect_pipe(&r2,1);
t1.send_message(100);
return 0;
}
步骤七:
? ? ? ? 由于接受者的个数也是不确定的,因此不能把数组写死,于是我采用一个向量vector记录接收者对象的指针,相关的函数或变量做一点点修改,运行结果如下:
I am a slot_show function!
num:100
I am a slot_print function!
num:100
I am a slot_print function!
num:100
#include <iostream>
#include <vector>
using namespace std;
class Receiver
{
public:
void (*fun)(int);//函数指针
Receiver(void (*pfun)(int))
{
this->fun=pfun;//函数指针初始化
}
};
void slot_show(int num)
{
cout<<"I am a slot_show function!"<<endl;
cout<<"num:"<<num<<endl;
}
void slot_print(int num)
{
cout<<"I am a slot_print function!"<<endl;
cout<<"num:"<<num<<endl;
}
class Transimiter
{
private://成员变量改为私有属性
vector <Receiver*> receiver_v;
public:
void send_message(int num)
{
for(vector <Receiver*>::iterator it=receiver_v.begin();it!=receiver_v.end();it++)//遍历器
{
(*it)->fun(num);//(*it)为实际的元素值
}
}
void connect_pipe(Receiver *pR)//建立管道连接
{
this->receiver_v.push_back(pR);
}
};
int main()
{
Transimiter t1;
Receiver r1(&slot_show);//定义两个不同的接收者对象
Receiver r2(&slot_print);
Receiver r3(&slot_print);
t1.connect_pipe(&r1);
t1.connect_pipe(&r2);
t1.connect_pipe(&r3);
t1.send_message(100);
return 0;
}
步骤八:
? ? ? ? 添加一个断开连接的函数,修改代码如下:
#include <iostream>
#include <vector>
using namespace std;
class Receiver
{
public:
void (*fun)(int);//函数指针
Receiver(void (*pfun)(int))
{
this->fun=pfun;//函数指针初始化
}
};
void slot_show(int num)
{
cout<<"I am a slot_show function!"<<endl;
cout<<"num:"<<num<<endl;
}
void slot_print(int num)
{
cout<<"I am a slot_print function!"<<endl;
cout<<"num:"<<num<<endl;
}
class Transimiter
{
private://成员变量改为私有属性
vector <Receiver*> receiver_v;
public:
void send_message(int num)
{
for(vector <Receiver*>::iterator it=receiver_v.begin();it!=receiver_v.end();it++)//遍历器
{
(*it)->fun(num);//(*it)为实际的元素值
}
}
void connect_pipe(Receiver *pR)//建立管道连接
{
this->receiver_v.push_back(pR);
}
void disconnect_pipe(Receiver *pR)
{
for(vector <Receiver*>::iterator it=receiver_v.begin();it!=receiver_v.end();it++)//遍历器
{
if((*it)==pR)
{
this->receiver_v.erase(it);
}
}
}
};
int main()
{
Transimiter t1;
Receiver r1(&slot_show);//定义两个不同的接收者对象
Receiver r2(&slot_print);
Receiver r3(&slot_print);
t1.connect_pipe(&r1);
t1.connect_pipe(&r2);
t1.connect_pipe(&r3);
t1.send_message(100);
t1.disconnect_pipe(&r1);
t1.disconnect_pipe(&r2);
t1.send_message(100);
return 0;
}