分类: LINUX
2010-10-20 13:51:50
早就想研究一下qte的qcop机制,今天有空研究了一下。
Qcop的过程可以分为,注册,发送,接收三部分。
一:注册:
QCopChannel * vaudioChannel = new QCopChannel( "QPE/Vaudio", this );
通过这句话,其实我们就已经完成了注册,它的内部实现是这样的。
简单的说就是把此channel的信息分别存放在此应用程序和服务器中,此应用程序存放的信息是这个字符串channel以及它对应的QCopChannel 指针链表,比如上例中的“this”,放在qcopClientMap中。
服务器中存放的是此字符串channel以及它对应的QWSClient 型指针链表,存放在qcopServerMap中。
其实这里的理解难度就在这个QWSClient中,它是怎么产生的?与qapplication有什么关系?
主要过程是这样的:
当服务器起来后它会打开一个管道,并且监听客户端的连接,如果有新的客户进来,就为此客户创建一个qwsClient。每个客户端在init_display里面会创建qt_fbdpy,在这里,客户端会发起向由统一的文件名指定的socket发起连接请求,于是在这里qwsclient被建立并且保存在服务器端,关键是是服务器为此client建立一个一个信号槽。
connect( client[socket], SIGNAL(readyRead()),this, SLOT(doClient()) );
这句很关键,每次客户端向服务器发送命令的时候,都是通过写管道实现的,客户端一写,服务器端也就可以读了,于是触发了doClient的执行,在里面处理客户端发过来的命令。
以下在个图应该可以说明一些:
二:发送信息:
发送过程主要是这样的:
用户一般这样调用
QCopChannel::send("QPE/Vaudio", "pause(long)", b);
而这个函数所做的,就是先向服务器发送命令,让服务器根据此channel字符串取出对应的QWSClient列表,然后向列表里面的每个客户端发送qcopEvent。
三:接收消息。
等到客户端调用qapp->exec()进入事件循环的时候,在fillqueue里面会去读自己的socket,放在队列里面。等数据读完后,返回,通过qwsProcessEvent,根据不同的事件类型调用不同的处理函数,对于qcop消息就是调用QCopChannel::sendLocally,在这个函数里面,就要用到qcopClientMap了,根据字符串channel,利用qcopClientMap返回QCopChannel指针列表,并对这些指针分别调用它们的信号receive,即emit received( msg, data ),于是触发了相应的slot函数,至于emit信号如何触发的槽函数我已经在qte通讯之signal-slot里说过了。
如图所示:
总结一下:
如果要利用qte提供的qcop机制,我想你做以下几步就可以了:
1, QCopChannel *channel = new QCopChannel(“channelName”,this);//注册
2, Connect(channel,SIGNAL(receive(….)),this,SLOT(processFunc(…)));//建立处理函数
3, 创建一个QApplication qapp;//必须要有此类才能建立与服务器之间的连接。
4, 调用qapp.exec();//必须要有它才能接收服务器发来的消息。