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;
}