日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Qt 進(jìn)程間通信

 芥子c1yw3tb42g 2023-09-22

Qt進(jìn)程間通信的方法:

  1. TCP/IP
  2. Local Server/Socket
  3. 共享內(nèi)存
  4. D-Bus (Unix庫(kù))
  5. QProcess
  6. 會(huì)話管理

TCP/IP :

使用套接字的方式,進(jìn)行通信(之前介紹了,這里就不介紹了)。

Local Server/Socket 

跨平臺(tái)Qt網(wǎng)絡(luò)模塊提供的類(lèi)使本地網(wǎng)絡(luò)編程變得可移植且簡(jiǎn)單。它提供了QLocalServer和QLocalSocket類(lèi),允許在本地設(shè)置中進(jìn)行類(lèi)似網(wǎng)絡(luò)的通信。它們的 TCP 對(duì)應(yīng)項(xiàng)可以用作直接替代品,以使跨網(wǎng)絡(luò)通信工作。(使用方法和TCP相似) 

QLocalServer :

使用方法:

  1. listen()監(jiān)聽(tīng)指定密鑰上的傳入連接
  2. 有客戶端連接時(shí),會(huì)發(fā)出newConnection()信號(hào)
  3. 使用nextPengingConnection()獲取連接的QLocalSocket
  4. close()關(guān)閉監(jiān)聽(tīng)

listen(QString)

監(jiān)聽(tīng)
close()關(guān)閉監(jiān)聽(tīng)
errorString()報(bào)告的當(dāng)前錯(cuò)誤的人類(lèi)可讀消息
fullServerName()返回服務(wù)器正在偵聽(tīng)的完整路徑
isListrening()服務(wù)器正在偵聽(tīng)傳入連接,true,否則為false
maxPendingConnection()返回掛起的接受連接的最大數(shù)目。默認(rèn)值為 30
nextPengingConnection()將一個(gè)掛起的連接作為連接的 QLocalServer 對(duì)象返回
serverName()則返回服務(wù)器名稱
socketOption()返回在套接字上設(shè)置的套接字選項(xiàng)
waitForNewConnection(int)堵塞多少毫秒或直到傳入連接可用

QLocalSocket

在Windows上是一個(gè)命名管道,在Unix上是一個(gè)本地套接字。

QLocalSocket 設(shè)計(jì)用于事件循環(huán),但也可以在沒(méi)有事件循環(huán)的情況下使用它。在這種情況下,您必須使用 waitForConnected()、waitForReadyRead()、waitForBytesWrite() 和 waitForDisconnected(),它們會(huì)阻止操作完成或超時(shí)到期。

使用方法:

  1. 使用connectToServer()與服務(wù)器簡(jiǎn)建立連接。
  2. 可以使用readData()讀取數(shù)據(jù),writeData()寫(xiě)入數(shù)據(jù)
  3. abort()斷開(kāi)連接
  4. close(),或disconnectFromServer()關(guān)閉套接字
connectToServer()連接服務(wù)器
bytesAvailable()獲取數(shù)據(jù)大小
error()返回上次發(fā)生的錯(cuò)誤類(lèi)型
flush()此函數(shù)盡可能多地從內(nèi)部寫(xiě)入緩沖區(qū)寫(xiě)入套接字,而不會(huì)阻塞。如果寫(xiě)入了任何數(shù)據(jù)返回true
fullServerName()返回套接字連接到的服務(wù)器路徑
isVaild()判斷套接字是否可用
readData()讀取數(shù)據(jù)
writeData()寫(xiě)入數(shù)據(jù)
setReadBufferSize()設(shè)置內(nèi)部緩沖區(qū)大小
waitForConnected()等待連接
waitForReadyRead()等待讀取
waitForBytesWrite()等待寫(xiě)入
waitForDisconnected()等待斷開(kāi)

 LoaclServer的搭建:

pro文件中添加:

QT  +network

在ui界面中添加:

QTextEdit 、QPushButton 和QLineEdit

.h文件:

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. #include<QLocalServer>
  5. #include<QLocalSocket>
  6. #include<QMessageBox>
  7. #include<QDataStream>
  8. QT_BEGIN_NAMESPACE
  9. namespace Ui { class Widget; }
  10. QT_END_NAMESPACE
  11. class Widget : public QWidget
  12. {
  13. Q_OBJECT
  14. public:
  15. Widget(QWidget *parent = nullptr);
  16. ~Widget();
  17. private slots:
  18. void on_pushButton_clicked();
  19. private:
  20. Ui::Widget *ui;
  21. QLocalServer *localserver;//服務(wù)端
  22. QLocalSocket*localsocket=nullptr;//套接字
  23. };
  24. #endif // WIDGET_H

.cpp文件:

  1. #include 'widget.h'
  2. #include 'ui_widget.h'
  3. Widget::Widget(QWidget *parent)
  4. : QWidget(parent)
  5. , ui(new Ui::Widget)
  6. {
  7. ui->setupUi(this);
  8. setWindowTitle('服務(wù)器端');
  9. localserver=new QLocalServer(this);
  10. localserver->listen('Good People');//Good People作為連接字符
  11. connect(localserver,&QLocalServer::newConnection,[=]()
  12. {
  13. localsocket=localserver->nextPendingConnection();//獲取連接的套接字
  14. connect(localsocket,&QLocalSocket::readyRead,[=]()//如果有可讀數(shù)據(jù)的話
  15. {
  16. QByteArray block;
  17. block=localsocket->readAll();
  18. QString S=block.data();
  19. ui->textEdit->append(QString('客戶端:%1').arg(S));
  20. });
  21. });
  22. }
  23. Widget::~Widget()
  24. {
  25. delete ui;
  26. }
  27. void Widget::on_pushButton_clicked()//發(fā)送數(shù)據(jù)
  28. {
  29. if(ui->lineEdit->text().isEmpty())
  30. {
  31. QMessageBox::information(this,'提示信息','請(qǐng)輸入內(nèi)容',QMessageBox::Ok);
  32. return;
  33. }
  34. ui->textEdit->setText(QString('服務(wù)器端:%1').arg(ui->lineEdit->text()));//設(shè)置內(nèi)容
  35. if(localsocket->isValid())
  36. {
  37. QString S=ui->lineEdit->text();
  38. localsocket->write(S.toUtf8());//發(fā)送消息
  39. }
  40. }

LocalSocket客戶端的搭建:

pro文件中添加:

QT +=network

ui界面中添加:

.h文件:

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. #include<QLocalSocket>
  5. #include<QMessageBox>
  6. QT_BEGIN_NAMESPACE
  7. namespace Ui { class Widget; }
  8. QT_END_NAMESPACE
  9. class Widget : public QWidget
  10. {
  11. Q_OBJECT
  12. public:
  13. Widget(QWidget *parent = nullptr);
  14. ~Widget();
  15. private slots:
  16. void on_pushButton_clicked();
  17. void on_pushButton_2_clicked();
  18. private:
  19. Ui::Widget *ui;
  20. QLocalSocket * localsocket;//套接字
  21. };
  22. #endif // WIDGET_H

.cpp文件:

  1. #include 'widget.h'
  2. #include 'ui_widget.h'
  3. Widget::Widget(QWidget *parent)
  4. : QWidget(parent)
  5. , ui(new Ui::Widget)
  6. {
  7. ui->setupUi(this);
  8. localsocket=new QLocalSocket(this);
  9. setWindowTitle('客戶端');
  10. connect(localsocket,&QLocalSocket::readyRead,[=]()
  11. {
  12. QByteArray block;
  13. block=localsocket->readAll();//讀取信息
  14. ui->textEdit->append(QString('服務(wù)器:%1').arg(block.data()));//聊天框添加信息
  15. });
  16. }
  17. Widget::~Widget()
  18. {
  19. delete ui;
  20. }
  21. void Widget::on_pushButton_clicked()//連接
  22. {
  23. localsocket->abort();//先斷開(kāi)
  24. localsocket->connectToServer('Good People');//連接
  25. }
  26. void Widget::on_pushButton_2_clicked()//發(fā)送
  27. {
  28. if(ui->lineEdit->text().isEmpty())
  29. {
  30. QMessageBox::information(this,'提示信息','請(qǐng)輸入內(nèi)容。',QMessageBox::Ok);
  31. return;
  32. }
  33. if(localsocket->isValid())
  34. {
  35. localsocket->write(ui->lineEdit->text().toUtf8());
  36. ui->textEdit->append(QString('客戶端:%1').arg(ui->lineEdit->text()));
  37. }
  38. }

運(yùn)行效果:

 共享內(nèi)存:

QSharedMemory

QSharedMemory 提供通過(guò)多個(gè)線程和進(jìn)程對(duì)共享內(nèi)存段的訪問(wèn)。它還為單個(gè)線程或進(jìn)程提供了一種鎖定內(nèi)存以進(jìn)行獨(dú)占訪問(wèn)的方法。

使用此類(lèi)時(shí),請(qǐng)注意以下平臺(tái)差異:

  • Windows:QSharedMemory 不“擁有”共享內(nèi)存段。當(dāng)將 QSharedMemory 實(shí)例附加到特定共享內(nèi)存段的所有線程或進(jìn)程都銷(xiāo)毀其 QSharedMemory 實(shí)例或退出時(shí),Windows 內(nèi)核會(huì)自動(dòng)釋放共享內(nèi)存段。
  • Unix:QSharedMemory“擁有”共享內(nèi)存段。當(dāng)將 QSharedMemory 實(shí)例附加到特定共享內(nèi)存段的最后一個(gè)線程或進(jìn)程通過(guò)銷(xiāo)毀其 QSharedMemory 實(shí)例與該段分離時(shí),Unix 內(nèi)核將釋放共享內(nèi)存段。但是,如果在未運(yùn)行 QSharedMemory 析構(gòu)函數(shù)的情況下最后一個(gè)線程或進(jìn)程崩潰,則共享內(nèi)存段將在崩潰中幸存下來(lái)。
  • HP-UX:每個(gè)進(jìn)程只允許一個(gè)附加到共享內(nèi)存段。這意味著 QSharedMemory 不應(yīng)在 HP-UX 中同一進(jìn)程中的多個(gè)線程中使用。

注意:由于是共享內(nèi)存,所以使用共享內(nèi)存之前使用lock()鎖定共享內(nèi)存,使用完后需要解鎖。當(dāng) QSharedMemory 的最后一個(gè)實(shí)例從共享內(nèi)存段分離時(shí),QSharedMemory 會(huì)自動(dòng)銷(xiāo)毀該段,并且不會(huì)保留對(duì)該段的引用。

常用函數(shù):

setKey(QString)設(shè)置此共享內(nèi)存對(duì)象的平臺(tái)獨(dú)立
setNativeKey()設(shè)置此共享內(nèi)存對(duì)象的特定于平臺(tái)的本機(jī)密鑰。如果 key 與當(dāng)前本機(jī)鍵相同,則函數(shù)返回而不執(zhí)行任何操作。
lock()對(duì)共享內(nèi)存上鎖
unlock()對(duì)共享內(nèi)存解鎖
size()返回附加的共享內(nèi)存段的大小。如果未連接共享內(nèi)存段,則返回 0。
isAttached()如果此進(jìn)程連接到共享內(nèi)存段返回true
errorString()錯(cuò)誤信息
detach()將進(jìn)程與共享內(nèi)存段分離。如果這是附加到共享內(nèi)存段的最后一個(gè)進(jìn)程,則系統(tǒng)將釋放共享內(nèi)存段,即內(nèi)容被銷(xiāo)毀。
data()返回指向共享內(nèi)存段內(nèi)容的指針(如果已連接)
create()使用傳遞給構(gòu)造函數(shù)的鍵創(chuàng)建大小為字節(jié)共享內(nèi)存段
constData()返回指向共享內(nèi)存段內(nèi)容的 const 指針(如果已連接)
attach()嘗試將進(jìn)程附加到由傳遞給構(gòu)造函數(shù)的鍵或?qū)?nbsp;setKey() 或 setNativeKey() 的調(diào)用標(biāo)識(shí)的共享內(nèi)存段。訪問(wèn)模式默認(rèn)為讀寫(xiě)

QSharedMemory::AccessMode

QSharedMemory::ReadOnly共享內(nèi)存段是只讀的。不允許寫(xiě)入共享內(nèi)存段。嘗試寫(xiě)入使用 ReadOnly 創(chuàng)建的共享內(nèi)存段會(huì)導(dǎo)致程序中止。
QSharedMemory::ReadWrite讀取和寫(xiě)入共享內(nèi)存段都是允許的。

基本使用流程:

 發(fā)送內(nèi)容到共享內(nèi)存

  1. 設(shè)置一個(gè)標(biāo)識(shí)  setKey();
  2. 使用isAttached()判斷進(jìn)程是否與共享內(nèi)存相連
  3. 使用detach()斷開(kāi)連接
  4. create(size)創(chuàng)建共享內(nèi)存
  5. 上鎖
  6. 將數(shù)據(jù)寫(xiě)入共享內(nèi)存
  7. 解鎖

從共享內(nèi)存中讀取數(shù)據(jù):

  1. attach()連接到共享內(nèi)存
  2. 上鎖
  3. 讀取數(shù)據(jù)
  4. 解鎖

例子:寫(xiě)入和讀取數(shù)據(jù)

  1. QSharedMemory memory;創(chuàng)建對(duì)象
  2. memory.setKey('1000');//設(shè)置標(biāo)識(shí)
  3. //寫(xiě)入數(shù)據(jù)
  4. if(memory.isAttached())//已經(jīng)連接的話
  5. {
  6. memory.detach();//斷開(kāi)連接
  7. }
  8. QString Str='SharedMemory';
  9. QBuffer buffer;
  10. buffer.open(QBuffer::ReadWrite);
  11. QDataStream S(&buffer);
  12. S<<Str;//將數(shù)據(jù)寫(xiě)到緩存中
  13. memory.create(buffer.size());//創(chuàng)建共享內(nèi)存
  14. memory.lock();//上鎖
  15. char * M=(char *)memory.data();//獲取memory的指針
  16. const char *N=buffer.data().data();//獲取緩存的指針
  17. memcpy(M,N,buffer.size());//把數(shù)據(jù)復(fù)制到共享內(nèi)存中
  18. memory.unlock();//解鎖
  19. //讀取數(shù)據(jù)
  20. memory.attach();//連接共享內(nèi)存
  21. QBuffer buffer1;
  22. QDataStream in(&buffer);
  23. QString Str1;
  24. memory.lock();//上鎖
  25. buffer.setData((char*)memory.constData(),memory.size());//存入數(shù)據(jù)
  26. buffer.open(QBuffer::ReadOnly);//只讀模式
  27. in>>Str1;//讀取數(shù)據(jù)
  28. memory.unlock();//解鎖
  29. memory.detach();//斷開(kāi)連接
  30. qDebug()<<Str1;

使用共享內(nèi)存實(shí)現(xiàn)兩個(gè)進(jìn)程的聊天:

ui界面:

.h文件:

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. #include<QSharedMemory>
  5. #include<QBuffer>
  6. #include<QMessageBox>
  7. #include<QDataStream>
  8. QT_BEGIN_NAMESPACE
  9. namespace Ui { class Widget; }
  10. QT_END_NAMESPACE
  11. class Widget : public QWidget
  12. {
  13. Q_OBJECT
  14. public:
  15. Widget(QWidget *parent = nullptr);
  16. ~Widget();
  17. private slots:
  18. void on_pushButton_clicked();
  19. void on_pushButton_2_clicked();
  20. void on_pushButton_3_clicked();
  21. private:
  22. Ui::Widget *ui;
  23. QSharedMemory sharedmemory;//共享內(nèi)存
  24. };
  25. #endif // WIDGET_H

.cpp文件:

  1. #include 'widget.h'
  2. #include 'ui_widget.h'
  3. #include<QDebug>
  4. Widget::Widget(QWidget *parent)
  5. : QWidget(parent)
  6. , ui(new Ui::Widget)
  7. {
  8. ui->setupUi(this);
  9. sharedmemory.setKey('GG');//設(shè)置標(biāo)識(shí)
  10. }
  11. Widget::~Widget()
  12. {
  13. delete ui;
  14. }
  15. void Widget::on_pushButton_clicked()//讀取數(shù)據(jù)
  16. {
  17. if(!sharedmemory.attach())
  18. {
  19. QMessageBox::information(this,'提示信息','連接共享內(nèi)存失敗',QMessageBox::Ok);
  20. return;
  21. }
  22. QBuffer buffer;
  23. QString S1;
  24. QDataStream in(&buffer);
  25. sharedmemory.lock();
  26. buffer.setData((char *)sharedmemory.constData(),sharedmemory.size());//設(shè)置數(shù)據(jù)
  27. buffer.open(QBuffer::ReadOnly);
  28. in>>S1;//讀取數(shù)據(jù)
  29. sharedmemory.unlock();//解鎖
  30. sharedmemory.detach();//斷開(kāi)連接
  31. ui->textEdit->append(QString('他人:%1').arg(S1));
  32. }
  33. void Widget::on_pushButton_2_clicked()//發(fā)送數(shù)據(jù)
  34. {
  35. if(sharedmemory.isAttached())//內(nèi)存和進(jìn)程連接
  36. {
  37. if(sharedmemory.detach())//斷開(kāi)連接
  38. {
  39. QMessageBox::information(this,'提示信息','已斷開(kāi)連接');
  40. }
  41. else
  42. {
  43. QMessageBox::information(this,'提示信息','斷開(kāi)連接失敗');
  44. return;
  45. }
  46. }
  47. if(ui->lineEdit->text().isEmpty())
  48. {
  49. QMessageBox::information(this,'提示信息','內(nèi)容不能為空。',QMessageBox::Ok);
  50. }
  51. QBuffer buffer;
  52. buffer.open(QBuffer::ReadWrite);
  53. QDataStream out(&buffer);
  54. QString Str=ui->lineEdit->text();
  55. out<<Str;//把內(nèi)容寫(xiě)入緩存區(qū)
  56. int size=buffer.size();
  57. if(!sharedmemory.create(size))
  58. {
  59. QMessageBox::information(this,'提示信息','內(nèi)存創(chuàng)建失敗',QMessageBox::Ok);
  60. return;
  61. }
  62. sharedmemory.lock();
  63. const char * Buff=buffer.data().data();//獲取buffer的指針
  64. char *Sha=(char *)sharedmemory.data();//獲取共享內(nèi)存的指針
  65. memcpy(Sha,Buff,qMin(sharedmemory.size(),size));
  66. sharedmemory.unlock();//解鎖
  67. ui->textEdit->append(QString('本人:%1').arg(ui->lineEdit->text()));//顯示信息
  68. }
  69. void Widget::on_pushButton_3_clicked()//斷開(kāi)連接
  70. {
  71. if(sharedmemory.detach())//斷開(kāi)連接
  72. {
  73. QMessageBox::information(this,'提示信息','已斷開(kāi)連接');
  74. }
  75. }

main函數(shù):

  1. #include 'widget.h'
  2. #include <QApplication>
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. Widget w1;
  7. w1.setWindowTitle('widget1');
  8. w1.show();//進(jìn)程1
  9. Widget w2;
  10. w2.setWindowTitle('widget2');
  11. w2.show();//進(jìn)程2
  12. return a.exec();
  13. }

這里解釋一下為什么要有斷開(kāi)連接的按鈕:

經(jīng)過(guò)多次測(cè)試發(fā)現(xiàn) :

A端發(fā)完數(shù)據(jù),B端接收數(shù)據(jù)后,A端需要主動(dòng)斷開(kāi)連接后B端才能正常發(fā)送數(shù)據(jù)。

(懂的大佬請(qǐng)?jiān)谠u(píng)論區(qū)解釋一下)

效果:

widget2 發(fā)送信息給widget1

 記住發(fā)送端需要主動(dòng)斷開(kāi)連接:

widget1 發(fā)送信息給 widget2

 QProcess

參考文章:關(guān)于Qt的QProcess進(jìn)程間雙向通信_(tái)qprocess進(jìn)程間通信_(tái)weixin_46424582的博客-CSDN博客

QProcess進(jìn)程間通信:

 主線程構(gòu)建思路:

  • 發(fā)送數(shù)據(jù)到子進(jìn)程:使用write()函數(shù)
  • 讀取子進(jìn)程發(fā)送的數(shù)據(jù)數(shù)據(jù):監(jiān)聽(tīng)readReadyStandardOutput()信號(hào)

創(chuàng)建一個(gè)項(xiàng)目:

ui界面中添加以下控件: textEdit   pushButton  lineEdit

.h文件:

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. #include<QProcess>
  5. #include<QMessageBox>
  6. #include<QDebug>
  7. QT_BEGIN_NAMESPACE
  8. namespace Ui { class Widget; }
  9. QT_END_NAMESPACE
  10. class Widget : public QWidget
  11. {
  12. Q_OBJECT
  13. public:
  14. Widget(QWidget *parent = nullptr);
  15. ~Widget();
  16. private slots:
  17. void on_pushButton_clicked();
  18. void on_pushButton_2_clicked();
  19. private:
  20. Ui::Widget *ui;
  21. QProcess *process;
  22. };
  23. #endif // WIDGET_H

.cpp文件:

  1. #include 'widget.h'
  2. #include 'ui_widget.h'
  3. Widget::Widget(QWidget *parent)
  4. : QWidget(parent)
  5. , ui(new Ui::Widget)
  6. {
  7. ui->setupUi(this);
  8. setWindowTitle('主進(jìn)程');
  9. process=new QProcess;
  10. connect(process,&QProcess::readyReadStandardOutput,[=]()//讀取信息
  11. {
  12. QString S=process->readAllStandardOutput().data();
  13. ui->textEdit->append(QString('子線程:%1').arg(S));
  14. });
  15. }
  16. Widget::~Widget()
  17. {
  18. delete ui;
  19. }
  20. void Widget::on_pushButton_clicked()//打開(kāi)子進(jìn)程
  21. {
  22. //子線程的開(kāi)啟
  23. process->start('D:/Qt_data/build-QProcess_text1-Desktop_Qt_5_9_9_MinGW_32bit-Debug/debug/QProcess_text1.exe');
  24. }
  25. void Widget::on_pushButton_2_clicked()//發(fā)送數(shù)據(jù)
  26. {
  27. if(ui->lineEdit->text().isEmpty())
  28. {
  29. QMessageBox::information(this,'提示信息','輸入框不能為空。',QMessageBox::Ok);
  30. return;
  31. }
  32. if(process->Running)
  33. {
  34. QString S=ui->lineEdit->text();//獲取lineEdit中的內(nèi)容
  35. process->write(S.toStdString().c_str());//寫(xiě)入數(shù)據(jù)
  36. ui->textEdit->append('父線程:'+S);//在聊天框顯示內(nèi)容
  37. }
  38. return;
  39. }

子線程的構(gòu)建思路:

  • 發(fā)送數(shù)據(jù)到父線程:使用文件打開(kāi) stdout,然后把數(shù)據(jù)寫(xiě)入stdout中
  • 獲取父線程發(fā)送過(guò)來(lái)的數(shù)據(jù):
    • linux中:使用QSocketNotifier 監(jiān)聽(tīng) stdin文件,當(dāng)改文件有變化是,讀取信息
    • Windows中:需要開(kāi)啟一個(gè)線程來(lái)管理stdin的文件變化,這個(gè)需要使用Windows API函數(shù)

這里介紹Windows中的子線程構(gòu)建:

創(chuàng)建一個(gè)項(xiàng)目:

在pro文件中添加:

QT +=concurrent

ui界面中添加:

 .h文件:

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. #include<QFile>
  5. #include<QSocketNotifier>
  6. #include<QBuffer>
  7. #include<QMessageBox>
  8. #include<QFuture>
  9. #include<QtConcurrent>
  10. #include<QIODevice>
  11. QT_BEGIN_NAMESPACE
  12. namespace Ui { class Widget; }
  13. QT_END_NAMESPACE
  14. class Widget : public QWidget
  15. {
  16. Q_OBJECT
  17. public:
  18. Widget(QWidget *parent = nullptr);
  19. ~Widget();
  20. private slots:
  21. void on_pushButton_clicked();
  22. void readStdin();//讀取數(shù)據(jù)
  23. private:
  24. Ui::Widget *ui;
  25. QFile file;
  26. signals:
  27. void sig_log(QString S);//顯示數(shù)據(jù)
  28. void sig_receivedCommand(QString S);//顯示數(shù)據(jù)
  29. };
  30. #endif // WIDGET_H

.cpp文件:

  1. #include 'widget.h'
  2. #include 'ui_widget.h'
  3. #include<iostream>
  4. #include<windows.h>
  5. #include<io.h>
  6. #include<fcntl.h>
  7. #include<QSocketNotifier>
  8. Widget::Widget(QWidget *parent)
  9. : QWidget(parent)
  10. , ui(new Ui::Widget)
  11. {
  12. ui->setupUi(this);
  13. setWindowTitle('子進(jìn)程');
  14. QFuture<void> fu=QtConcurrent::run(this,&Widget::readStdin);//開(kāi)啟一個(gè)線程
  15. connect(this,&Widget::sig_receivedCommand,this,[&](QString s)
  16. {
  17. ui->textEdit->append('父線程:'+s);
  18. });
  19. connect(this,&Widget::sig_log,this,[=](QString s)
  20. {
  21. ui->textEdit->append('父線程:'+s);
  22. });
  23. }
  24. Widget::~Widget()
  25. {
  26. delete ui;
  27. }
  28. void Widget::readStdin()//讀取數(shù)據(jù)
  29. {
  30. bool ok=true;
  31. char chbuf[1024];//緩存
  32. DWORD dwRead;//32位無(wú)符號(hào)整數(shù)
  33. HANDLE hStdinDup;//HANDLE 句柄類(lèi)型
  34. const HANDLE hStdin=GetStdHandle(STD_INPUT_HANDLE);//GetStdHandle獲取標(biāo)準(zhǔn)輸入的句柄
  35. if(hStdin==INVALID_HANDLE_VALUE)//為無(wú)效句柄的話
  36. return;
  37. DuplicateHandle(GetCurrentProcess(),hStdin,
  38. GetCurrentProcess(),&hStdinDup,0,false,DUPLICATE_SAME_ACCESS);//創(chuàng)建一個(gè)新句柄
  39. CloseHandle(hStdin);//關(guān)閉舊句柄
  40. while(ok)
  41. {
  42. ok=ReadFile(hStdinDup,chbuf,sizeof(chbuf),&dwRead,NULL);//讀取hstdinDup句柄文件中的數(shù)據(jù)
  43. emit sig_log(QLatin1String('ok is:')+QString::number(ok));
  44. if(ok &&dwRead!=0)
  45. {
  46. emit sig_receivedCommand(QString::fromUtf8(chbuf,dwRead));//讀取數(shù)據(jù)
  47. }
  48. }
  49. }
  50. void Widget::on_pushButton_clicked()//發(fā)送數(shù)據(jù)
  51. {
  52. if(ui->lineEdit->text().isEmpty())
  53. {
  54. QMessageBox::information(this,'提示信息','輸入框不能為空。',QMessageBox::Ok);
  55. return;
  56. }
  57. QFile fileout;
  58. if(fileout.open(stdout,QIODevice::WriteOnly))
  59. {
  60. QString S=ui->lineEdit->text();
  61. fileout.write(S.toStdString().c_str());
  62. ui->textEdit->append('子線程:'+S);
  63. fileout.close();//關(guān)閉文件
  64. }
  65. }

運(yùn)行效果:

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多