成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深度解析 Qt 內(nèi)部進(jìn)程通信機(jī)制

移動(dòng)開(kāi)發(fā)
在 Qt 系統(tǒng)中,不僅有著構(gòu)造完善的系統(tǒng)結(jié)構(gòu),而且為了滿足用戶對(duì)編寫圖形用戶界面應(yīng)用的種種需求,它還創(chuàng)建了許多新的系統(tǒng)機(jī)制,其中 Qt 所特有的內(nèi)部進(jìn)程通信機(jī)制尤其值得一提。

Qt 內(nèi)部進(jìn)程通信機(jī)制是本文要介紹的內(nèi)容,Qt 作為一種跨平臺(tái)的基于 C++ 的 GUI 系統(tǒng),能夠提供給用戶構(gòu)造圖形用戶界面的強(qiáng)大功能。自從 1996 年 Qt 被 Trolltech 公司發(fā)布以來(lái),該系統(tǒng)成為世界上很多成功的圖形用戶應(yīng)用所使用的主要系統(tǒng)。更為重要的是,Linux 操作系統(tǒng)的桌面環(huán)境系統(tǒng) KDE 也是基于 Qt 構(gòu)造的。目前,Qt 已經(jīng)提供了對(duì)包括 MS/Windows、Unix/X11 和嵌入式平臺(tái)的支持,得到了越來(lái)越廣泛的應(yīng)用。

Qt 系統(tǒng)中,不僅有著構(gòu)造完善的系統(tǒng)結(jié)構(gòu),而且為了滿足用戶對(duì)編寫圖形用戶界面應(yīng)用的種種需求,它還創(chuàng)建了許多新的系統(tǒng)機(jī)制,其中 Qt 所特有的內(nèi)部進(jìn)程通信機(jī)制尤其值得一提。 本文分析了基于 QT 的應(yīng)用進(jìn)程之間通信常用的三種機(jī)制:QCOP 協(xié)議,Signal-Slot 機(jī)制和 FIFO 機(jī)制。給出了各自的使用方法,并指出了各自的使用場(chǎng)合。

1、 QCOP協(xié)議

QCOP 是 Qt 內(nèi)部的一種通信協(xié)議,這種協(xié)議用于不同的客戶之間在同一地址空間內(nèi)部或者不同的進(jìn)程之間的通信。目前,這種機(jī)制還只在 Qt 的嵌入式版本中提供。

為實(shí)現(xiàn)這種通信機(jī)制Qt 中包括了由 QObject 類繼承而來(lái)的 QCopChannel 類,該類提供了諸如 send()、isRegistered() 等靜態(tài)函數(shù),它們可以在脫離對(duì)象的情況下使用。為了在 channel 中接收通信數(shù)據(jù),用戶需要構(gòu)造一個(gè) QCopChannel 的子類并提供 receive() 函數(shù)的重載函數(shù),或者利用 connect() 函數(shù)與接收到的信號(hào)相聯(lián)系。

值得一提的是,在 Qt 系統(tǒng)中,只提供了 QCOP 協(xié)議機(jī)制和用于接收消息的類,而如何發(fā)送消息則沒(méi)有提供相應(yīng)的類供用戶使用。

在基于 Qt 的桌面系統(tǒng) Qtopia(QPE)中,則提供了相應(yīng)的發(fā)送類:QCopEnvelope。用戶可以通過(guò)該類利用 channel 向其他進(jìn)程發(fā)送消息。該類將通過(guò) QCopChannel 發(fā)送 QCop 消息的過(guò)程進(jìn)行了封裝,用戶只需要調(diào)用該類中的相關(guān)函數(shù)就可以方便地實(shí)現(xiàn)進(jìn)程之間的通信過(guò)程。一方面,QCop 消息的發(fā)送要利用 QCopEnvelope 類,另一方面,接收消息則是通過(guò)與一個(gè) QCopChannel 相關(guān)聯(lián)。

在發(fā)送消息時(shí),將利用如下的協(xié)議機(jī)制:

  1. QCopEnvelope e(channelname, messagename); 

 
對(duì)于需要攜帶參數(shù)的消息,必須使用"<<()"運(yùn)算符將參數(shù)添加到envelope中。

  1. << parameter1 << parameter2 << ...

對(duì)于不帶參數(shù)的消息,只需要利用: 

  1. QCopEnvelope e(channelname, messagename); 

在Qtopia中,所有的channels名都以"QPE/"開(kāi)始,而messagename則是一個(gè)函數(shù)的標(biāo)識(shí)符。

在接收消息時(shí),通常只需要利用在應(yīng)用程序中預(yù)先定義好的QPE/Application/{appname}管道,當(dāng)然,也可以根據(jù)需要自己定義管道,并將其與一個(gè)slot函數(shù)相關(guān)聯(lián):

  1. myChannel = new QCopChannel( "QPE/FooBar", this );  
  2. connect( myChannel, SIGNAL(received(const QCString &, const QByteArray &)),  
  3.           this, SLOT(fooBarMessage( const QCString &, const QByteArray &)) ); 

下面將具體的通信過(guò)程舉例如下:

在需要接收消息的類(如Window1)中定義管道:

  1. QCopChannel *doChannel = new QCopChannel("QPE/Do", this);  
  2.  connect(doChannel, SIGNAL(received(const QCString &, const QByteArray &)),   
  3.   this, SLOT(doMessage(const QCString &, const QByteArray &))); 

同時(shí),需要在該類中定義相應(yīng)的消息處理函數(shù)doMessage,

  1. void Window1::doMessage(const QCString &msg, const QByteArray &args)  
  2. {  
  3.  QDataStream stream(args, IO_ReadOnly);  
  4.  if(msg == "Message1(QString)")  
  5.  {  
  6.   QString text;  
  7.   stream >> text;  
  8.   button->setText(text);  
  9.  }  
  10.  else if(msg == "Message2()")  
  11.  {  
  12.   close();  
  13.  }  

其中的Message1(QString)和Message2(QString)都是用戶自己定義的消息,該函數(shù)中分別對(duì)這些消息進(jìn)行了相應(yīng)的處理。在該例中當(dāng)收到帶有參數(shù)的Message1消息時(shí),將該字符串參數(shù)stream顯示在按鈕button上;當(dāng)收到Message2消息時(shí),將執(zhí)行關(guān)閉Window1窗口的動(dòng)作,當(dāng)然用戶可以根據(jù)需要自行編寫相應(yīng)的處理過(guò)程。

另一方面,在類Class2中需要發(fā)出消息的函數(shù)function中利用QCopEnvelope發(fā)送消息:

  1. void Class2::function()  
  2. {   QCopEnvelope e("QPE/Do", "Message1(QString)");  
  3.     e << param; } 

這里發(fā)出了Message1消息,并將需要攜帶的參數(shù)param發(fā)送到管道中。

通過(guò)這樣的過(guò)程,用戶可以很方便地實(shí)現(xiàn)不同對(duì)象、不同進(jìn)程之間通信過(guò)程,而且可以根據(jù)需要在通信過(guò)程中任意傳遞參數(shù)。

#p#

2、 信號(hào)-槽(Signal-Slot)機(jī)制

Qt中,有一種用于對(duì)象之間的通信:信號(hào)-槽機(jī)制,這種機(jī)制是Qt的核心機(jī)制,也是它區(qū)別于其他GUI工具的最主要的特征。在大多數(shù)GUI工具中,通常為可能觸發(fā)的每種行為定義一個(gè)回調(diào)函數(shù),這個(gè)回調(diào)函數(shù)是一個(gè)指向函數(shù)的指針。在Qt中,信號(hào)-槽機(jī)制取代了這種繁雜的函數(shù)指針,能夠?qū)崿F(xiàn)同樣的功能。信號(hào)-槽機(jī)制可以攜帶任意類型、任意數(shù)量的參數(shù),而且完全是安全的,不會(huì)引起系統(tǒng)的崩潰。

所有由QObject類繼承而來(lái)的類,或者是它的一個(gè)子類,都可以包括信號(hào)-槽機(jī)制。信號(hào)通常是當(dāng)對(duì)象改變他們的狀態(tài)時(shí)發(fā)出的,這就是一個(gè)對(duì)象在需要與其他對(duì)象通信時(shí)所需要做的一切,它并不知道是否有其他對(duì)象在另一端接收該信號(hào)。從這個(gè)意義上來(lái)說(shuō),這種機(jī)制實(shí)現(xiàn)了真正的信息封裝,確保了對(duì)象可以被當(dāng)作一個(gè)獨(dú)立的軟件構(gòu)件來(lái)使用。

而槽可以被用于接收信號(hào),它們通常是類中的成員函數(shù)。一個(gè)槽并不知曉是否有一個(gè)信號(hào)與自己相聯(lián)系,同樣,包含有槽函數(shù)的對(duì)象也對(duì)通信機(jī)制一無(wú)所知,它們也可以作為一個(gè)獨(dú)立的軟件構(gòu)件。

用戶可以按照需要將許多信號(hào)與一個(gè)單獨(dú)的槽函數(shù)相聯(lián)系,一個(gè)信號(hào)也可以按需要被聯(lián)系到很多不同的槽函數(shù)。甚至還可以將一個(gè)信號(hào)直接與另一個(gè)信號(hào)相聯(lián)系,這樣當(dāng)***個(gè)信號(hào)被發(fā)出時(shí)立刻發(fā)出第二個(gè)信號(hào)。

這樣,信號(hào)-槽相結(jié)合就產(chǎn)生了一種功能強(qiáng)大的編程機(jī)制。

例如:

  1. button = new QAction(tr("button"), QIconSet(QPixmap("button.png")), 0, 0, this);  
  2. connect(button, SIGNAL(activated()), this, SLOT(slotButton())); 

程序中定義了一個(gè)按鈕,并利用connect()函數(shù)將該按鈕button的activated()信號(hào)與slotButton()函數(shù)相關(guān)聯(lián),當(dāng)用戶觸發(fā)按鈕時(shí),就會(huì)執(zhí)行相應(yīng)的槽函數(shù)。當(dāng)然,這里的信號(hào)是QAction類中預(yù)先定義好的信號(hào),用戶在使用該機(jī)制時(shí),可以根據(jù)需要自行定義信號(hào),同時(shí)在適當(dāng)?shù)臅r(shí)候利用emit語(yǔ)句發(fā)出該信號(hào)。另外,在信號(hào)和相應(yīng)的槽函數(shù)之間還可以傳遞任意參數(shù),如:

  1. emit signal(parameter); 

 
3、 FIFO機(jī)制

當(dāng)然,除了 Qt 內(nèi)部所特有的通信機(jī)制之外,一般操作系統(tǒng)中常用的進(jìn)程通信機(jī)制同樣可以用于 Qt 系統(tǒng)內(nèi)部不同進(jìn)程之間的通信。如消息隊(duì)列、共享內(nèi)存、信號(hào)量、管道等機(jī)制,其中有些機(jī)制,如信號(hào)量,在 Qt 中重新進(jìn)行了封裝;有些機(jī)制則可以直接調(diào)用操作系統(tǒng)的系統(tǒng)調(diào)用來(lái)實(shí)現(xiàn)。這里,有名管道是一種簡(jiǎn)單實(shí)用的通信機(jī)制,用戶在對(duì)Qt內(nèi)部機(jī)制

不甚了解的情況下,同樣可以使用這種方法實(shí)現(xiàn)對(duì)象進(jìn)程之間的通信。下面就對(duì)利用這種機(jī)制實(shí)現(xiàn)Qt內(nèi)部進(jìn)程之間的通信過(guò)程進(jìn)行介紹。

首先,需要?jiǎng)?chuàng)建 FIFO,這個(gè)過(guò)程類似于創(chuàng)建文件,在系統(tǒng)中可以利用 mkfifo 命令來(lái)創(chuàng)建,這樣就可以用 open 函數(shù)打開(kāi)它,同時(shí),一般的文件 I/O函數(shù)(close、read、write)都可以用于 FIFO。

在基于 Qt 的應(yīng)用中,有很多應(yīng)用采用了一種客戶機(jī)-服務(wù)器模式,這時(shí)就可以利用 FIFO 在客戶機(jī)和服務(wù)器之間傳遞數(shù)據(jù)。例如,有一個(gè)服務(wù)器,它負(fù)責(zé)接收底層程序發(fā)來(lái)的消息,同時(shí),它與很多客戶機(jī)有關(guān),服務(wù)器需要將收到的不同消息發(fā)送到不同的客戶機(jī),而每個(gè)客戶機(jī)也有請(qǐng)求需要發(fā)給服務(wù)器,進(jìn)而發(fā)給底層程序。

下面是服務(wù)器端的程序示例:(架設(shè)已有客戶端進(jìn)程為讀而打開(kāi)/dev/fifoclient1和/dev/fifoclient1)

  1. fd = open("/dev/fifoserver", O_NONBLOCK|O_RDONLY);  
  2.    file = fdopen(fd, "r");   
  3. ret = fgets(buf, MAX_LINE, file );  
  4.   if(buf[0] == '0')  
  5.   {   
  6.    QFile fd_file("/dev/fifoclient1");  
  7.    QString temp(buf);  
  8.    if(fd_file.open(IO_WriteOnly|IO_Append)) {  
  9.          QTextStream t(&fd_file);  
  10.   t<< temp;     
  11.     fd_file.close();  
  12.   }  
  13.   else if(buf[0] == '1')  
  14.   {   
  15.    QFile fd_file("/dev/fifoclient2");  
  16.    QString temp(buf);  
  17.    if(fd_file.open(IO_WriteOnly|IO_Append)) {  
  18.          QTextStream t(&fd_file);  
  19.   t<< temp;     
  20.     fd_file.close();  
  21.   } 

在該程序中,服務(wù)器接收底層發(fā)來(lái)的信息(這里假設(shè)也是由 FIFO 管道傳來(lái)),然后根據(jù)收到的信息內(nèi)容,如***個(gè)字節(jié)的內(nèi)容,將信息發(fā)到不同客戶端的管道中,實(shí)現(xiàn)對(duì)信息的正確分發(fā)。

客戶端程序示例如下:(假設(shè)服務(wù)器端已經(jīng)為讀而打開(kāi) /dev/fifo 管道)

  1. QFile out_file("/dev/fifo");  
  2.  if(out_file.open(IO_WriteOnly|IO_Append)) {  
  3.   QTextStream t(&out_file);    
  4. << text << "\n";  } 

當(dāng)任意一個(gè)客戶端需要向服務(wù)器發(fā)送消息時(shí),就可以通過(guò) /dev/fifo 這個(gè)公共的管道發(fā)出。

通過(guò)這種方式,同樣可以實(shí)現(xiàn)GUI內(nèi)部不同進(jìn)程或應(yīng)用之間的通信過(guò)程,但是,當(dāng)客戶端數(shù)量較多時(shí),這種方法就顯示出了一定的局限性,整個(gè)通信過(guò)程布局變得過(guò)于繁雜,管道越來(lái)越多使得出錯(cuò)的可能性也越來(lái)越大。因此,利用 FIFO 實(shí)現(xiàn) Qt 中上述客戶端和服務(wù)器端的通信過(guò)程,更適用于客戶端應(yīng)用較少時(shí)。

小結(jié):Qt 內(nèi)部進(jìn)程通信機(jī)制的內(nèi)容介紹完了,希望本文對(duì)你有所幫助,更多資料請(qǐng)參考編輯推薦。

責(zé)任編輯:zhaolei 來(lái)源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-06-22 17:27:19

QT 進(jìn)程通信

2011-06-24 14:01:34

Qt QCOP 協(xié)議

2011-07-01 15:04:49

Qt 內(nèi)省

2011-06-22 17:09:50

QT 進(jìn)程 通信

2011-06-27 09:15:21

QT Creator

2011-07-01 14:39:08

Qt Quick

2011-08-02 18:07:03

iPhone 內(nèi)省 Cocoa

2011-06-09 14:56:53

QT 編譯

2021-07-06 21:30:06

Linux進(jìn)程通信

2010-11-25 09:37:14

MySQL查詢緩存機(jī)制

2011-06-16 15:17:16

2011-06-29 10:46:01

Qt Eembedded Linux

2016-10-09 14:41:40

Swift開(kāi)發(fā)ARC

2021-02-26 08:17:57

操作系統(tǒng)信號(hào)量

2011-06-21 14:01:07

QT 界面庫(kù) Embedded

2011-06-24 13:08:34

Qt Qt 4.5.3 移植

2011-06-21 18:02:14

Qt 動(dòng)態(tài) 鏈接庫(kù)

2017-09-05 10:20:30

PyTorchTensorPython

2024-12-20 16:46:22

Spring三級(jí)緩存

2011-06-21 15:48:41

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 久久久久91 | 日韩欧美在线视频播放 | 欧美黑人国产人伦爽爽爽 | 成年女人免费v片 | 最新超碰 | av一级毛片 | 亚洲精品久久久久久久久久久久久 | 亚洲成人黄色 | 国产精品久久国产精品 | 国产精品久久久久久吹潮日韩动画 | 国产午夜精品理论片a大结局 | 日日夜夜精品视频 | 亚洲精品免费在线观看 | 久久精品天堂 | 美日韩免费视频 | 日韩中文字幕在线观看 | 成人av一区 | 日韩成人在线免费视频 | 国产精品久久久久久久久久久久冷 | 久草影视在线 | 欧美性猛片aaaaaaa做受 | 狼人伊人影院 | 久久1区 | 91久久北条麻妃一区二区三区 | 精品福利在线 | 亚洲天堂影院 | av毛片在线免费观看 | 日韩av一区二区在线观看 | 久久精品国产一区二区电影 | 97影院2| 青青艹在线视频 | 看片wwwwwwwwwww | 中文字幕在线观看一区 | 亚洲第一成年免费网站 | 欧美成人专区 | 一区二区三区亚洲 | 国产你懂的在线观看 | 久久免费精品视频 | 国产精品久久久久久久久图文区 | 日韩1区2区 | 91精品国产一区二区三区动漫 |