一文读懂Qt信号与槽的机制

发布时间:2024年01月13日

????????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;
}
文章来源:https://blog.csdn.net/YDY5659150/article/details/135566843
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。