1. 程式人生 > >Qt工作筆記-程序間的通訊(通過QSharedMemory)

Qt工作筆記-程序間的通訊(通過QSharedMemory)

程式執行截圖如下:

分享端分享圖片:

接受端接受圖片:

分享端的邏輯:

1.建立一個QSharedMemory,並設定一個key值;

2.檢視這個記憶體是不是被使用,如果被使用就斷開;

3.呼叫create進行建立;

4.使用memcpy把要寫入的資料放入QSharedMemory中(內部一般會使用互斥鎖技術,鎖住資源)

讀取端邏輯:

1.建立一個QSharedMemory,把key值設定為分享端相同的key值;

2.使用attach連線上這個QSharedMemory;

3.以讀取位元組的方式讀取QSharedMemory中的資料(內部一般會使用互斥鎖技術,鎖住資源);

4.使用detach埠對這個QSharedMemory的連線。

原始碼如下:

接收端:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class QSharedMemory;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

public slots:
    void btnClicked();

private:
    Ui::Widget *ui;

    QSharedMemory *m_sharedMemory;
};

#endif // WIDGET_H

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"

#include <QDebug>
#include <QBuffer>
#include <QDataStream>
#include <QImage>
#include <QPixmap>
#include <QSharedMemory>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(btnClicked()));

    m_sharedMemory=new QSharedMemory("169254");
}

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

void Widget::btnClicked(){
    if(!m_sharedMemory->attach()){
        qDebug()<<"SharedMemory attach failed!";
        return;
    }
    QBuffer buffer;
    QDataStream in(&buffer);
    QImage image;

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

    ui->label->setPixmap(QPixmap::fromImage(image));

}

分析端:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class QSharedMemory;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

public slots:
    void btnClicked();

private:
    Ui::Widget *ui;
    QSharedMemory *m_sharedMemory;
};

#endif // WIDGET_H

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"

#include <QBuffer>
#include <QFileDialog>
#include <QDataStream>
#include <QSharedMemory>
#include <QDebug>
#include <QPixmap>
#include <QImage>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(btnClicked()));

    m_sharedMemory=new QSharedMemory("169254");
}

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

void Widget::btnClicked()
{
    if(m_sharedMemory->isAttached()){
        if(!m_sharedMemory->detach()){
            qDebug()<<"sharedMemory detach falied!";
            return;
        }
    }

    QString fileName=QFileDialog::getOpenFileName(this,"","","Images(*.*)");
    QImage image(fileName);
    ui->label->setPixmap(QPixmap::fromImage(image).scaled(128,128));

    QBuffer buffer;
    buffer.open(QBuffer::ReadWrite);
    QDataStream out(&buffer);
    out<<image;

    if(!m_sharedMemory->create(buffer.size())){
        qDebug()<<m_sharedMemory->errorString()<<" created failed!";
        return;
    }

    m_sharedMemory->lock();
    char *to=(char*)m_sharedMemory->data();
    const char *from=buffer.data().data();
    memcpy(to,from,qMin(m_sharedMemory->size(),(int)buffer.size()));
    m_sharedMemory->unlock();
}