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

  在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())
    {
        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));



共享内存的工程分享

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值