QT学习之路十四(进程通信——系统剪切板和共享内存)
2017-06-02 00:10
155 查看
在Linux中,进程之间存在多种通信方式:管道通信、信号通信、共享内存、信号量、消息队列和套接字。
截屏程序最关键的就是使用QPixmap的grabWindow方法,去抓取屏幕的winId,然后赋给一个QPixmap对象,将其显示即可。
上面pixmap是一个QPixmap的对象,show为一个QLabel对象,scaled方法可以使截得的图片按比例显示于Label中。
截完屏之后,便可以把得到的图片放入系统剪切板,
在另一个进程中粘贴便实现了进程的通信。
这个截屏小程序中还运用到了文件保存对话框,右键菜单等功能,有兴趣的朋友可以去下载:http://pan.baidu.com/s/1mhRMmpi
共享内存和其他的方法其实都是类似的思想(除了套接字),就是先找一个缓冲区,将需要分享的东西存放于缓冲区,然后另一个进程去这个缓冲区寻找。
在QT中,有一个现成的共享内存类QSharedMemory,在显示的时候,可以先利用QBuffer来存放缓冲的内容,然后再将QBuffer中的内容进行memcpy,放到共享内存中去。另一个进程读取的时候也是相同的步骤,只是反过来了而已。
注意:每次访问共享内存的时候需要对共享内存进行上锁,访问结束后再解锁。
文件中加载图片放到共享内存:
共享内存读取图片
共享内存的工程分享
系统剪切板
以上这几种是经常在书本上或者百度上出现的方式,最近在做一个截屏小程序的时候,发现其实还有其他的方法,那就是系统剪切板。截屏程序最关键的就是使用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));
共享内存的工程分享
相关文章推荐
- Linux 系统编程笔记 守护进程,进程通信
- Linux\Unix IPC进程通信实例分析(一):共享内存通信---系统V
- 撸代码--linux进程通信(基于共享内存)
- Android系统分析之AIDL跨进程通信机制的使用和原理分析
- LoRa点对点系统4 进程通信
- UNIX系统中的进程通信之共享内存
- 撸代码--linux进程通信(基于共享内存)
- linux使用共享内存通信的进程同步退出问题
- Linux——基于共享内存 消息队列和基于Socket的进程间的通信
- 同一台系统下的用户进程之间的通信理解
- Linux下的C编程实战(开发平台搭建,文件系统编程,进程控制与进程通信编程,“线程”控制与“线程”通信编程,驱动程序设计,专家问答)
- Linux下C编程,进程通信之标准流管道通信(即系统调用)
- Linux下C编程,进程通信之标准流管道通信(即系统调用)
- 分布式系统中进程通信的理解
- unix系统中进程间的通信
- 系统——进程线程,同步与通信
- 通过Python脚本理解系统进程间通信 推荐
- c# wcf NetNamePipeBinding 实现同一系统上不同进程之间的通信
- 关于Linux下进程间使用共享内存和信号量通信的时的编译问题
- 进程之间的通信-剪切板