首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >C++在Linux上从剪贴板获取字符串

C++在Linux上从剪贴板获取字符串
EN

Stack Overflow用户
提问于 2014-12-09 11:52:11
回答 2查看 10.2K关注 0票数 10

你好,我正在写一个c++程序,我需要把剪贴板上的东西变成一个字符串变量。我找到了很多解决方案,但它们都是为windows编写的。有没有不使用QT库的方法?我发现了一些与X11相关的东西,但也不是很明确。

非常感谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-09 12:23:37

你有没有试着先找到一个程序,而不是一个代码?我为你做了这件事,发现了很多使用直接X11调用的实现。我认为最有价值的是this,但你也可以阅读this。只要找到任何程序并查找源代码即可。尝试在维基百科上查找哪些应用程序使用x11剪贴板/选择系统。

以下程序专门在数据传输机制上运行:

xcutsel将数据从选择传输到cut缓冲区,反之亦然

xclipboardglipper (Gnome)、parcellite (LXDE)和klipper (KDE)都是剪贴板管理器,也许wmcliphist也可以使用xcb显示剪切缓冲区的内容,并允许用户对其进行操作。

xclipxselxcopy是将数据复制到X选择或从X选择复制数据的命令行程序。xcopy有一个详细选项,可以帮助调试X选择问题。parcellite还具有从命令行读取和写入特定X选择的能力。

synergy是一个跨平台工具,允许您在运行多个操作系统的多台计算机之间共享剪贴板

xfce4-clipman-plugin是一个“Xfce4面板的剪贴板历史插件”,同时也是一个剪贴板管理器xtranslate在多语言词典中查找X选择中的单词自动剪切同步剪切缓冲区和选择缓冲区

简而言之,在理论上,X11有两个“剪贴板”:实际上是一个键盘,用于选择--你立即选择的文本可以通过按下鼠标中键粘贴到你想要的任何地方,而实际的“键盘”是为了主/默认剪贴板的目的而制作的,作为不同类型的对象交换。

另外,在我的经历之后,我不会再和x11一起工作了。享受:)

票数 2
EN

Stack Overflow用户

发布于 2017-07-09 04:20:39

X11使用灵活的多缓冲区、多格式、异步应用程序端剪贴板协议。

大多数工具包都实现了它(GTK的gtk_clipboard_get()、Qt的QApplication::clipboard()、Tk的clipboard_get)。但您可以使用X11 API手动完成此操作,例如,如果您不使用工具包,或者如果您必须通过剪贴板缓冲区传递大量数据,而不同时将其全部保存在内存中。

理论

可能有很多缓冲区,但您只需要知道两个:

  • CLIPBOARD是通常的显式缓冲区:您可以使用编辑/复制菜单复制内容,然后使用编辑/粘贴将其粘贴。menu.
  • PRIMARY选择是一种隐式鼠标选择功能:当使用鼠标光标选择文本时,文本将进入其中,在文本输入字段中单击鼠标中键时,文本将从中粘贴。

主选择不需要按键,因此它对于在相邻的窗口之间复制小片段很有用。这个特性主要是unix特有的,但我见过putty、trillian和一些gtk应用程序在Windows操作系统上模拟它。此外,当用鼠标中键点击页面的非交互空白区域时,firefox还具有“粘贴并转到”功能。

为了优化这些东西,这些都是application-side缓冲区:应用程序只需告诉服务器“我拥有它”,而不是在每次更改时将整个剪贴板/选择推送到服务器。要获取buffer,您需要所有者将其内容提供给您。这样,即使是一个大的缓冲区也不会占用任何资源,直到它真正被请求。

在请求缓冲区时,您可以向所有者询问所需的特定格式。例如,从seamonkey浏览器复制的图像(右键单击图像并按“复制图像”)可以用不同的格式表示。如果您将其粘贴到终端中,它将显示为图像URL。如果您将其粘贴到libreoffice writer中,它将成为从该URL加载的图片。如果粘贴到gimp中,它将是图像本身。这是因为seamonkey很聪明,它为每个应用程序提供了它所要求的格式:终端使用文本字符串,libreoffice使用html,gimp使用图像数据。要请求文本格式,您需要使用回退到STRINGUTF8_STRING格式。

当您请求另一个应用程序准备缓冲区时,这可能需要一些时间,请求是asynchronous:所有者准备缓冲区,将其保存在指定位置(窗口属性用作临时存储),并在完成时通过SelectionNotify事件通知您。

因此,要获取缓冲区:

  • 选择缓冲区名称(CLIPBOARDPRIMARY)、格式(UTF8_STRINGSTRING)和窗口属性以将结果存储到
  • 调用XConvertSelection()以请求缓冲区<代码>H227<代码>H128等待<代码>D29事件<代码>H230<代码>H131从窗口属性读取缓冲区内容<代码>H232<代码>F233

朴素的实现

代码语言:javascript
运行
AI代码解释
复制
// gcc -o xclipget xclipget.c -lX11
#include <stdio.h>
#include <limits.h>
#include <X11/Xlib.h>

Bool PrintSelection(Display *display, Window window, const char *bufname, const char *fmtname)
{
  char *result;
  unsigned long ressize, restail;
  int resbits;
  Atom bufid = XInternAtom(display, bufname, False),
       fmtid = XInternAtom(display, fmtname, False),
       propid = XInternAtom(display, "XSEL_DATA", False),
       incrid = XInternAtom(display, "INCR", False);
  XEvent event;

  XConvertSelection(display, bufid, fmtid, propid, window, CurrentTime);
  do {
    XNextEvent(display, &event);
  } while (event.type != SelectionNotify || event.xselection.selection != bufid);

  if (event.xselection.property)
  {
    XGetWindowProperty(display, window, propid, 0, LONG_MAX/4, False, AnyPropertyType,
      &fmtid, &resbits, &ressize, &restail, (unsigned char**)&result);

    if (fmtid == incrid)
      printf("Buffer is too large and INCR reading is not implemented yet.\n");
    else
      printf("%.*s", (int)ressize, result);

    XFree(result);
    return True;
  }
  else // request failed, e.g. owner can't convert to the target format
    return False;
}

int main()
{
  Display *display = XOpenDisplay(NULL);
  unsigned long color = BlackPixel(display, DefaultScreen(display));
  Window window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0,0, 1,1, 0, color, color);
  Bool result = PrintSelection(display, window, "CLIPBOARD", "UTF8_STRING") ||
                PrintSelection(display, window, "CLIPBOARD", "STRING");
  XDestroyWindow(display, window);
  XCloseDisplay(display);
  return !result;
}

这将适用于许多简单的情况。这里缺少的一点是对大缓冲区的增量读取的支持。让我们添加它!

大缓冲区

一些应用程序可能想要复制/粘贴100 to的文本日志。而X11允许这样做!但数据必须以增量方式传递,并拆分成块。

如果请求的缓冲区太大,则owner会设置格式为INCR的属性,而不是将其存储到窗口属性中。如果你删除了它,owner会假设你已经读过了,并将下一个块放在同一个属性中。这一过程一直持续到最后一个块被读取和删除。最后,owner设置大小为0的属性来标记数据的结尾。

因此,要读取大缓冲区,请删除INCR属性并等待该属性再次出现(PropertyNotify事件,状态为== PropertyNewValue),读取并删除它,等待它再次出现,依此类推,直到它以零大小出现。

代码语言:javascript
运行
AI代码解释
复制
// gcc -o xclipget xclipget.c -lX11
#include <stdio.h>
#include <limits.h>
#include <X11/Xlib.h>

Bool PrintSelection(Display *display, Window window, const char *bufname, const char *fmtname)
{
  char *result;
  unsigned long ressize, restail;
  int resbits;
  Atom bufid = XInternAtom(display, bufname, False),
       fmtid = XInternAtom(display, fmtname, False),
       propid = XInternAtom(display, "XSEL_DATA", False),
       incrid = XInternAtom(display, "INCR", False);
  XEvent event;

  XSelectInput (display, window, PropertyChangeMask);
  XConvertSelection(display, bufid, fmtid, propid, window, CurrentTime);
  do {
    XNextEvent(display, &event);
  } while (event.type != SelectionNotify || event.xselection.selection != bufid);

  if (event.xselection.property)
  {
    XGetWindowProperty(display, window, propid, 0, LONG_MAX/4, True, AnyPropertyType,
      &fmtid, &resbits, &ressize, &restail, (unsigned char**)&result);
    if (fmtid != incrid)
      printf("%.*s", (int)ressize, result);
    XFree(result);

    if (fmtid == incrid)
      do {
        do {
          XNextEvent(display, &event);
        } while (event.type != PropertyNotify || event.xproperty.atom != propid || event.xproperty.state != PropertyNewValue);

        XGetWindowProperty(display, window, propid, 0, LONG_MAX/4, True, AnyPropertyType,
          &fmtid, &resbits, &ressize, &restail, (unsigned char**)&result);
        printf("%.*s", (int)ressize, result);
        XFree(result);
      } while (ressize > 0);

    return True;
  }
  else // request failed, e.g. owner can't convert to the target format
    return False;
}

int main()
{
  Display *display = XOpenDisplay(NULL);
  unsigned long color = BlackPixel(display, DefaultScreen(display));
  Window window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0,0, 1,1, 0, color, color);
  Bool result = PrintSelection(display, window, "CLIPBOARD", "UTF8_STRING") ||
                PrintSelection(display, window, "CLIPBOARD", "STRING");
  XDestroyWindow(display, window);
  XCloseDisplay(display);
  return !result;
}

例如,对于大于4000的缓冲区,xsel工具使用INCR传输。根据ICCCM的说法,这取决于应用程序选择一个合理的大小限制。

同样的代码也适用于PRIMARY选择。将"CLIPBOARD“替换为"PRIMARY”以打印PRIMARY选择内容。

参考文献

-XPaste() Lindsey

票数 34
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27378318

复制
相关文章
在Linux上用Eclipse写C++程序
我厂很多同学使用VC在windows上编写linux的C/C++程序,然后再传的开发服务器上,然后再编译和调试。如果有修改,可能会直接用vi去改了,然后再把源代码同步回来。其实这样做挺折腾的。也有大神全盘vim设置emacs写,想来也是极好的。 但是,也有另外一个方案,就是在 Linux上安装个写C/C++程序的IDE,这样可以直接编写、编译、运行、上传SVN,非常方便。其实要做到这点,也很简单: 你需要一个虚拟机来运行一个带GUI的LINUX,这样IDE才能运行起来,当然也可以直接在开发服务器上安
韩伟
2018/03/05
3.5K0
在Linux上用Eclipse写C++程序
在剪贴板上读取/写入数据,太方便了吧!
说起处理数据,就离不开导入导出,而我们使用Pandas时候最常用的就是read_excel、read_csv了。
朱小五
2021/01/20
2.6K0
从 GitHub 上获取文件内容
企鹅号小编
2018/01/04
4.8K0
从 GitHub 上获取文件内容
从 GitHub 上获取文件内容
我依稀记得 Java 的 Spring Cloud 中有一个重要的部分就是集中配置:
凌虚
2020/07/20
2K0
从 GitHub 上获取文件内容
在Linux上通过可写文件获取root权限的多种方式
在Linux中,一切都可以看做文件,包括所有允许/禁止读写执行权限的目录和设备。当管理员为任何文件设置权限时,都应清楚并合理为每个Linux用户分配应有的读写执行权限。在本文中我将为大家展示,如何利用Linux中具有写入权限的文件/脚本来进行提权操作。想要了解更多关于Linux系统权限的内容,可以阅读这篇文章。好了,话不多说。下面就进入我们的正题吧!
FB客服
2018/07/30
4.4K0
在Linux上通过可写文件获取root权限的多种方式
在 C++ 中标记字符串
theme: channing-cyan highlight: a11y-dark
鲸落c
2022/11/14
5590
在Linux上安装python
和在Windows安装Python的教程一样,安装python要配置环境pyenv,只是python要手工使用Linux命令安装,使用这种方法最好有一点Linux基础。由于笔者使用这种方法没有安装成功,就搬砖给大家看一下了
Py_lover
2018/07/26
4K0
在 Linux 上使用 BusyBox
它的所有命令都被编译到一个二进制文件里(busybox),它的手册只有 81 页(根据我对 man 送到 pr 管道的计算),但它涵盖了近 400 条命令。作为一个例子的比较,这是 “原版” 的 useradd —help 的输出:
用户8989785
2021/10/13
2.7K0
在Linux上安装Kibana
首先要做的:关闭防火墙。 centos7用“service firewalld stop” centos6用“service iptables stop”
星哥玩云
2022/07/14
2.5K0
在 Linux 上使用 gImageReader 从图像和 PDF 中提取文本
本上,OCR(光学字符识别)引擎可以让你从图片或文件(PDF)中扫描文本。默认情况下,它可以检测几种语言,还支持通过 Unicode 字符扫描。
用户8639654
2021/09/09
3.1K0
linux c++开发环境_玩转 WSL 在 Win10 上打造 Linux 开发环境
WSL 是 Windows Subsystem for Linux 的简称, 可让开发人员按原样运行 GNU/Linux 环境 - 包括大多数命令行工具、实用工具和应用程序 - 且不会产生虚拟机开销。
用户7886150
2021/02/15
2.6K0
在 Linux 上使用 Multitail
当你想同时查看多个文件(尤其是日志文件)的活动时,multitail 命令会非常有用。它的工作方式类似于多窗口形式的 tail -f 命令。也就是说,它显示这些文件的底部和添加的新行。虽然通常使用简单,但是 multitail 提供了一些命令行和交互式选项,在开始使用它之前,你应该了解它们。
用户8639654
2021/09/22
2K0
Linux上安装Boost C++ Libraries
Boost C++ 库(Libraries)是一组扩充C++功能性的经过同行评审(Peer-reviewed)且开放源代码程序库。大多数的函数为了能够以开放源代码、封闭项目的方式运作,而授权于Boost软件授权条款(Boost Software License)之下。许多Boost的开发人员是来自C++标准委员会,而部份的Boost库成为C++的TR1标准之一。[1]
大江小浪
2018/07/25
2.3K0
Linux系统上如何获取mac地址
link/ether 70:ca:9b:ce:67:ae brd ff:ff:ff:ff:ff:ff
用户8418197
2021/03/30
7.3K0
21天,在Github上获取 6300 star
大家好,我是程序员小吴。12月初我在GitHub上上传了一个仓库,到现在为止获取了 6300 star,下面和大家聊聊关于项目启动的初衷、面临的一些困难和未来的计划。
五分钟学算法
2019/01/23
1.1K0
在Manjaro Linux上安装Julia
如果我们直接搜索Julia在Manjaro Linux下的安装方法,很有可能搜到一个类似于参考链接4中所提供的方案。这个方案是从官网下载一个可执行文件,然后将该文件存放到系统路径下。虽然这也不失为一个比较通用的方法,但是我个人更倾向于从系统的源里面去寻找资源,而Manjaro Linux其实是有julia的资源的,只是会有一些依赖需要我们去独立安装。我们先尝试一下直接安装julia:
不知名站长
2021/03/31
2.4K0
在Manjaro Linux上安装Julia
在Linux上狩猎Netwire RAT
如今攻击者可以选择多种 RAT,现在的这些 RAT 不仅针对 Windows 而是跨平台的(如 CrossRAT、Pupy 与 Netwire)。尽管此前有大量的研究针对 Windows 与 macOS 版本的 Netwire,但是 Linux 版本的 Netwire 却鲜为人知。
FB客服
2020/04/14
1.6K0
在Linux上狩猎Netwire RAT
在 Ubuntu Linux 上安装 Dropbox
下载相应的 DEB 文件。考虑到你使用的是 64 位的 Ubuntu,请获取 64 位版本的 DEB 文件。
用户9105998
2021/11/22
2.5K0
在 Ubuntu Linux 上安装 AnyDesk
AnyDesk 是一个流行的远程桌面软件,可用于 Linux、Windows、BSD、macOS 和移动平台。
用户8639654
2021/10/11
3.3K0
在 Kali Linux 上安装 OpenVAS
OpenVAS,一种端点扫描应用程序和 Web 应用程序,用于识别和检测漏洞。它被公司广泛用作风险缓解解决方案的一部分,以快速识别其生产甚至开发服务器或应用程序中的差距。这不是一个完整的解决方案,但它可以帮助您修复可能无法发现的常见安全漏洞。
紫禁玄科
2022/11/24
2.8K0
在 Kali Linux 上安装 OpenVAS

相似问题

如何从Qclipboard mimeData在c++中获取剪贴板图像?

12

c++ linux -从IP获取接口

21

在Linux上如何获取Linux()?

13

使用GetText从剪贴板获取文本-避免在空剪贴板上出现错误

21

如何从C++程序中获取Linux上的主板ID

54
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文