QT中进程之间通信

Linux中进程之间通信有,pipe,signal,消息队列,共享内存,信号量,socket.

Qt中提供的进程间通信有如下几种:

1.TCP/IP

跨平台的QNetwork提供了众多的类来实现网络编程.比如QNetworkAccessManger,Qftp等来使用指定的应用程序协议.

2.共享内存

在Linux中也有这个通信方式,通信方式是非常常用额,也比较简单.本文用共享内存来举例.

3.D-Bus

QtDBus模块是一个Unix库,可以使用D-Bus协议来实现进程间的通信

4.Qt通信协议(QCOP)

QCopChannel实现客户端程序使用有名管道来进行消息传输的协议.QCopChannel仅仅在在做嵌入式Linux上才能够使用.


新建一个Gui应用项目,

#include <QtGui/QApplication>
#include "dialog.h"
#include <QTextCodec>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
    Dialog w;
    w.show();
    
    return a.exec();
}

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QSharedMemory>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT
    
public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
    
private:
    Ui::Dialog *ui;
    void detach();
    QSharedMemory shareMemory;

public slots:
    void loadFromFile();
    void loadFromMemory();

private slots:
    void on_pushButton_clicked();
    void on_pushButton_2_clicked();
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"
#include <QFileDialog>
#include <QBuffer>
#include <QDebug>

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    shareMemory.setKey("Linux_Google");
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::loadFromFile()
{
    if(shareMemory.isAttached()) /* 判断该进程是否已经连接到共享内存段 */
        detach();
    ui->label->setText(tr("选择一个图片文件"));
    QString fileName = QFileDialog::getOpenFileName(0,QString(),QString(tr("Images(*.png *.jpg)")));

    QImage image;
    if(!image.load(fileName))
    {
        ui->label->setText(tr("选择的文件不是图片文件,选择图片文件"));
        return;
    }
    ui->label->setPixmap(QPixmap::fromImage(image));

    QBuffer buffer;  /* QBuffer用来暂存图片 */
    buffer.open(QBuffer::ReadWrite);
    QDataStream out(&buffer);   /* QDataStream从数据流冲去读取buffer数据 */
    out << image;
    int size = buffer.size();
    if(!shareMemory.create(size)){ /* 自动将该内存段连接到本进程上 */
        ui->label->setText(tr("无法创建共享内存段"));
        return;
    }

    shareMemory.lock();
    char *to = (char *)shareMemory.data(); /* 强制转换一个地址 */
    const char *from=buffer.data().data();
    memcpy(to,from,qMin(shareMemory.size(),size));
    shareMemory.unlock();
}

void Dialog::loadFromMemory()
{
    if(!shareMemory.attach()){
        ui->label->setText(tr("无法连接到共享内存段,请先添加一张图片"));
        return;
    }

    QBuffer buffer;
    QDataStream in(&buffer);
    QImage image;

    shareMemory.lock();
    buffer.setData((char*)shareMemory.constData(), shareMemory.size());
    buffer.open(QBuffer::ReadOnly);
    in >> image;
    shareMemory.unlock();

    shareMemory.detach();
    ui->label->setPixmap(QPixmap::fromImage(image));
}

void Dialog::detach()
{
    if (!shareMemory.detach())
        ui->label->setText(tr("无法从共享内存中分离"));
}

void Dialog::on_pushButton_clicked()
{
    loadFromFile();
}

void Dialog::on_pushButton_2_clicked()
{
    loadFromMemory();
}


界面效果如下:



                                                                                                                           文章出自:Linux_Google

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页