首页 > 技术文章 > Qt进程间通信

AmyBKLP 2019-10-20 21:10 原文

QProcess允许将一个进程视为顺序IO设备

#include<QProcess>

private:

    QProcess myprocess;

 

void MainWindow::on_pushButton_clicked()

{

  myprocess.start("notepad.exe");   // 启动进程

}

 

2  进程间通信 IPC(Inter-Process Communication):

  1)TCP/IP

  2)   共享内存:

    QSharedMemory 跨平台的共享内存类,提供了访问操作系统共享内存的实现,允许多个线程和进程安全访问共享内存段。

    QSystemSemaphore可用于控制系统的共享资源的访问及进程间访问

  3) D-BUS

    允许从一个进程发射信号关联到另一个进程的槽上

  4) Qt通信协议(QCOP):linux应用

    QCopChannel类实现了在客户端程序间使用有名管道来进行消息传输的协议

 

 

QSharedMemory sharedMemory;

// 设置key,系统用它作为底层共享内存段的标识
sharedMemory.setKey("QSharedMemoryExample");

 1 #include "dialog.h"
 2 #include "ui_dialog.h"
 3 
 4 #include <QFileDialog>
 5 #include <QBuffer>
 6 #include <QDebug>
 7 
 8 Dialog::Dialog(QWidget *parent) :
 9     QDialog(parent),
10     ui(new Ui::Dialog)
11 {
12     ui->setupUi(this);
13     // 设置key,系统用它作为底层共享内存段的标识
14     sharedMemory.setKey("QSharedMemoryExample");
15 }
16 
17 Dialog::~Dialog()
18 {
19     delete ui;
20 }
21 
22 void Dialog::loadFromFile()
23 {
24     if (sharedMemory.isAttached())   //判断该进程是否已经连接到共享内存段
25         detach();                    //如果是,那么调用detach()先将该进程与共享内存段进行分离 
26 
27     ui->label->setText(tr("选择一个图片文件!"));
28     QString fileName = QFileDialog::getOpenFileName(0, QString(), QString(),        
29                                                     tr("Images (*.png *.jpg)"));            
30     QImage image;
31     if (!image.load(fileName)) {
32         ui->label->setText(tr("选择的文件不是图片,请选择图片文件!"));
33         return;
34     }
35     ui->label->setPixmap(QPixmap::fromImage(image));
36 
37     // 将图片加载到共享内存
38     QBuffer buffer;
39     buffer.open(QBuffer::ReadWrite);
40     QDataStream out(&buffer);
41     out << image;
42     int size = buffer.size();
43     if (!sharedMemory.create(size)) {             //create 函数创建指定大小的共享内存段,自动将共享内存段连接到本进程
44         ui->label->setText(tr("无法创建共享内存段!"));
45         return;
46     }
47     sharedMemory.lock();
48     char *to = (char*)sharedMemory.data();
49     const char *from = buffer.data().data();
50     memcpy(to, from, qMin(sharedMemory.size(), size));     //使用memcpy将buffer对应的数据段复制到共享内存段
51     sharedMemory.unlock();
52 }
53 
54 void Dialog::loadFromMemory()
55 {
56     if (!sharedMemory.attach()) {
57         ui->label->setText(tr("无法连接到共享内存段,\n"
58                               "请先加载一张图片!"));
59         return;
60     }
61 
62     QBuffer buffer;
63     QDataStream in(&buffer);
64     QImage image;
65 
66     sharedMemory.lock();
67     buffer.setData((char*)sharedMemory.constData(), sharedMemory.size());
68     buffer.open(QBuffer::ReadOnly);
69     in >> image;
70     sharedMemory.unlock();
71 
72     sharedMemory.detach();                               //现在已经不需要使用共享内存了。所以调用detach函数将进程与共享内存段进行分离
73     ui->label->setPixmap(QPixmap::fromImage(image));
74 }
75 
76 void Dialog::detach()
77 {
78     if (!sharedMemory.detach())
79         ui->label->setText(tr("无法从共享内存中分离!"));
80 }
81 
82 // 从文件中加载图片按钮
83 void Dialog::on_loadFromFileButton_clicked()
84 {
85     loadFromFile();
86 }
87 
88 // 从共享内存显示图片
89 void Dialog::on_loadFromSharedMemoryButton_clicked()
90 {
91     loadFromMemory();
92 }

 

    

推荐阅读