您的位置:首页 > 编程语言 > Qt开发

QT学习之路十四(进程通信——系统剪切板和共享内存)

2017-06-02 00:10 155 查看
  在Linux中,进程之间存在多种通信方式:管道通信、信号通信、共享内存、信号量、消息队列和套接字。

系统剪切板

  以上这几种是经常在书本上或者百度上出现的方式,最近在做一个截屏小程序的时候,发现其实还有其他的方法,那就是系统剪切板。

  截屏程序最关键的就是使用QPixmap的grabWindow方法,去抓取屏幕的winId,然后赋给一个QPixmap对象,将其显示即可。

this->pixmap = QPixmap::grabWindow(QApplication::desktop()->winId());
ui->show->setPixmap(this->pixmap.scaled(ui->show->size()));

上面pixmap是一个QPixmap的对象,show为一个QLabel对象,scaled方法可以使截得的图片按比例显示于Label中。

截完屏之后,便可以把得到的图片放入系统剪切板,

QClipboard *clipborad = QApplication::clipboard();
clipborad->setPixmap(this->pixmap);

在另一个进程中粘贴便实现了进程的通信。

这个截屏小程序中还运用到了文件保存对话框,右键菜单等功能,有兴趣的朋友可以去下载:http://pan.baidu.com/s/1mhRMmpi

共享内存

  共享内存的实现我使用了一个qt的dome,在帮助文档中搜索Shared Memory example,即可得到详细的介绍和源代码解释。

  共享内存和其他的方法其实都是类似的思想(除了套接字),就是先找一个缓冲区,将需要分享的东西存放于缓冲区,然后另一个进程去这个缓冲区寻找。

  在QT中,有一个现成的共享内存类QSharedMemory,在显示的时候,可以先利用QBuffer来存放缓冲的内容,然后再将QBuffer中的内容进行memcpy,放到共享内存中去。另一个进程读取的时候也是相同的步骤,只是反过来了而已。

  注意:每次访问共享内存的时候需要对共享内存进行上锁,访问结束后再解锁。

文件中加载图片放到共享内存:

void MainWindow::loadfileslot()
{
//判断是否存在共享内存
if(this->memory.isAttached())
4000

{
this->memory.detach();             //清空共享内存
}
QString filename = QFileDialog::getOpenFileName(this, "Open Image", QString(), tr("*.png *.bmp *jpg"));
//加载
QImage image;
if(!image.load(filename))
{
QMessageBox::information(this, "Error Message", "Image Load Error");
return;
}
ui->label->setPixmap(QPixmap::fromImage(image));

//写入共享内存
//QBuffer是一个文件读写界面,但是文件是在内存中的
QBuffer buffer;         //可以进行读写
bool ok = buffer.open(QIODevice::ReadWrite);
if(ok)
{
QDataStream in(&buffer);
in<<image;
}
else
{
QMessageBox::information(this, "Error Message", "Write Buffer Error");
return;
}
int size = buffer.size();
if(!memory.create(size))
{
QMessageBox::information(this, "Error Message", "Unable to create shared memory segment.");
return;
}
memory.lock();
char* to = (char*)memory.data();
const char *from = buffer.data().data();
memcpy(to, from, qMin(memory.size(), size));
memory.unlock();
}


共享内存读取图片

//判断是否存在共享内存
if(!this->memory.attach())
{
QMessageBox::information(this, "Error Message", "Unable to attach to shared memory segment");
return;
}

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

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

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


共享内存的工程分享
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: