信号和槽函数看来不是那么好理解,只熟悉MFC框架的我更是看不懂信号槽。所以整了个服务器的QT程序,用这个场景来研究信号槽函数。
服务器,窗口类mainwindow 服务器监听类server 每个连接产生socket类Tcpclientsocket
发现原则1:这个类需要声明实现 自己的槽函数 不需要声明要接的信号 而要声明要发给别的类的信号
发现原则2:这个类需要#include进 要给它自己发信号的类的头文件
发现原则3:这个类头文件需要声明一个,它#include进的要给它自己发信号的类的指针,或者不包含给信号的类指针 局部new
Tcpclientsocket *tcpClientSocket = new Tcpclientsocket(this);
发现原则4:要发给谁,不需要引入这个目标类的头文件。要从别处接,就得引入那个给信号类的头文件,因为在写connect时候得用
发现原则5:本类下 connect绑定的都是别的类发给自己的信号,和自己定义的槽函数 不能绑别的类的槽函数 废话
发现原则6:与基类信号connect 发出方参数都是this,最下层那个类 Tcpclientsocket connect的信号都是 QTcpSocket(基类)自带信号
Tcpclientsocket的
connect(this,SIGNAL(readyRead()),this,SLOT(dataReceived()));
connect(this,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));
发现原则7:如果有个信号,和自己发给别的类的信号名字相同 也是可以的
Tcpclientsocket 接 基类给的信号disconnected 自己也给server发 void disconnected(int);
发现原则8:在一个类的头文件里,ctrl+鼠标左键信号,不会跳转,因为信号都是发出给别人的,看看此类头文件#inlcude包含的头文件,那个就是信号来源
发现原则9:有些槽函数是基类的虚函数,需要实现,在头文件里一般写到protected:下
server的
protected:
void incomingConnection(int socketDescriptor);
是QTcpServer的
protected:
virtual void incomingConnection(qintptr handle);
基类QTcpSocket里 下就没有protected的虚函数
Tcpclientsocket类的readyRead信号 定义在QIODevice
QTcpSocket的基类是QAbstractSocket,QAbstractSocket的基类是QIODevice
发现原则10:一个类的头文件里 有好多槽函数,但是#include却不包含该工程里的其他类头文件
说明它是最底下的一个类,connect只与基类连接 都是this
发现原则11:信号总是发给别的类的,在头文件里看不到自己会接收什么信号,只有在实例化要给自己发信号的类的指针后,connect之后才会知道。
connect的时机,一般是给这个类包含的那个 给信号类实例化时绑定。
发现原则12:在connect看关系,只能看到接收,看不到这个类要发给谁,就是这个类的槽函数都接啥。在emit处才能看到发给谁