linux桌面软件(wps)内嵌到其他窗口

news2024/12/24 11:44:45

程序测试环境是:slackware系统,属于linux系统,有桌面(Xface Session)。系统镜像是:slackware64-15.0-install-dvd.iso。qt、c++代码实现。

程序功能:将已经打开的wps(word、pdf等都可以)软件界面内嵌到qt窗口里。

必要条件:slackware系统里需要安装wps、qt5开发工具,本篇文章不做详述。

编译说明:上图是测试demo编译时,在编译工程里加的依赖。 以下截图的部分代码,其他代码不做描述。

form.h:

#ifndef FORM_H
#define FORM_H

#include <QWidget>
#include <QProcess>

namespace Ui {
class Form;
}

class Form : public QWidget
{
    Q_OBJECT

public:
    explicit Form(QWidget *parent = nullptr);
    ~Form();

    void find_window_id_in_tree();

    void find_window_id_by_class();

    void add_window_in_qt(WId id);

private:
    Ui::Form *ui;
    QProcess *process;
};

#endif // FORM_H

 form.cpp

#include "form.h"
#include "ui_form.h"
#include <QWindow>
#include <QVBoxLayout>
#include <QtX11Extras/QX11Info>
#include <xcb/xcb.h>
#include <QDebug>
#include <X11/Xlib.h> 
#include <X11/Xatom.h> 
#include <iostream>  
#include <vector>  
#include <string>  
#include <sstream>  
#include <fstream>

Form::Form(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form)
{
    ui->setupUi(this);
    find_window_id_in_tree();
    find_window_id_by_class();
}

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

// 通过系统窗口树形结构去一层层遍历窗口(我这里没有遍历子窗口,如果找不到某个窗口,或许是因为是子窗口)
void Form::find_window_id_in_tree()
{
    Display *display = XOpenDisplay(nullptr);
    if (!display) {
        std::cerr << "Cannot open display\n";
        return;
    }
    Window root = DefaultRootWindow(display);
    Window parent, *children;
    unsigned int num_children;

    if (!XQueryTree(display, root, &root, &parent, &children, &num_children)) {
        return;
    }

    std::vector<Window> windows;
    windows.push_back(root);
    for (unsigned int i = 0; i < num_children; ++i) {
        windows.push_back(children[i]);
    }
    XFree(children);

    for (Window win : windows) {
        char* name;
        int status = XFetchName(display, win, &name);
        if (status == 1) {
            // 这里的win就是窗口的id,也是窗口的句柄值
            std::cout << "Found window name: " << name << " " << win << std::endl;
            if (std::string(name).find("wps") != std::string::npos) {
//                XFree(name);
//                return;
            }
            XFree(name);
        }

        // 递归检查子窗口(如果有的话)
        // 注意:这里为了简化示例,没有实现递归
    }
}

// 将第三方软件(wps)窗口内嵌到qt窗口里
void Form::add_window_in_qt(WId id)
{
     QWindow *win = QWindow::fromWinId(id);
     QWidget *widget = QWidget::createWindowContainer(win);
     widget->setParent(this);
     QVBoxLayout *layout = new QVBoxLayout();
     layout->addWidget(widget);
     this->setLayout(layout);
}

// 获取窗口id(句柄)(找到的另外一种比较快捷的拿到窗口句柄的方式)
void Form::find_window_id_by_class()
{
    Display* display = XOpenDisplay(NULL);
    if (!display) {
        std::cerr << "Failed to open display" << std::endl;
        return;
    }

    Atom netClientListAtom = XInternAtom(display, "_NET_CLIENT_LIST", False);
    Atom actualType;
    int format;
    unsigned long numItems, bytesAfter;
    unsigned char* data = NULL;

    int status = XGetWindowProperty(display, DefaultRootWindow(display),
                                    netClientListAtom, 0, ~0UL, False,
                                    AnyPropertyType,
                                    &actualType, &format, &numItems, &bytesAfter,
                                    &data);


    if (status == Success && actualType == XA_WINDOW) {
        Window* windows = reinterpret_cast<Window*>(data);
        for (unsigned long i = 0; i < numItems; ++i) {

            Window win = windows[i];
            Atom actualType;
            int format;
            unsigned long nitems;
            unsigned long bytes_after;
            unsigned char* prop_data = nullptr;

            // 获取WM_CLASS属性
            if (XGetWindowProperty(display, win, XInternAtom(display, "WM_CLASS", False), 0, 1024, False, XA_STRING,
                                &actualType, &format, &nitems, &bytes_after, &prop_data) == Success) {
                std::string className(reinterpret_cast<char*>(prop_data));
                if (actualType == XA_STRING && className == "wpspdf") {
                    std::cout << "Window class name for window " << win << ": " << className << std::endl;
                    XFree(prop_data);

                    add_window_in_qt(win);
                }
            }
        }
    } else {
        std::cerr << "Failed to get window list property" << std::endl;
    }

    if (data != NULL) {
        XFree(data);
    }

    XCloseDisplay(display);
}


代码需要说明的有如下几点:

1、wps在slackware 中安装好后,可以打开word、pdf、execl、ppt,他们分别对应的可执行文件是wps、wpspdf、et、wpp。

2、本次demo测试,是将pdf窗口内嵌到qt窗口。

3、代码逻辑有些随意,主要是用于测试。效果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2170332.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【优选算法】(第五篇)

目录 ⻓度最⼩的⼦数组&#xff08;medium&#xff09; 题目解析 讲解算法原理 编写代码 ⽆重复字符的最⻓⼦串&#xff08;medium&#xff09; 题目解析 讲解算法原理 编写代码 ⻓度最⼩的⼦数组&#xff08;medium&#xff09; 题目解析 1.题目链接&#xff1a;. - …

分割数组的最大值

题目链接 分割数组的最大值 题目描述 注意点 0 < nums[i] < 10^61 < nums.length < 10001 < k < min(50, nums.length) 解答思路 首先需要理解题意&#xff0c;需要将这个数组分成 k 个非空的连续子数组&#xff0c;找到划分组合中子数组和的最大值最小…

el-table+el-form实现表单校验和解决不垂直居中导致的问题

el-tableel-form实现表单校验 1.实现el-table的表单校验 关键点123 2.解决不垂直居中导致的问题 问题效果图 解决方案 .item-align-center {display: inline-flex; }

OJ在线评测系统 原生Java代码沙箱核心实现流程三 整理封装输出结果 拿到程序执行时间(stopwatch类) 和 运行内存

我们在之前的操作中已经拿到程序进行了编译和运行 接下来我们要将我们的结果输出 整理输出 // 4.收集整理输出结果 ExecuteCodeResponse executeCodeResponse new ExecuteCodeResponse(); ArrayList<String> outputList new ArrayList<>();for (ExecuteMessage…

Library介绍(一)

之前和大家介绍过cell delay是如何计算的。那么&#xff0c;本文将着重和大家介绍一些timing lib中的各个参数定义是什么意思。会分以下几个部分介绍&#xff1a;库属性描述、时序弧介绍、环境描述、单元描述。之前介绍的cell delay template就是单元描述中的一部分。本文主要介…

网络安全入门必备:这四点你做到了吗?

数据的鸿沟无疑是显而易见的&#xff0c;网络安全领域亟需熟练的专业人员。 组织在这方面投入巨大资金&#xff0c;但挑战依旧存在。 根据最新的研究&#xff0c;有64%的违规行为是导致机构过去一年收入损失及/或罚款的主要原因。 60%的组织在努力招聘网络安全人才&#xff…

【市场解读】新能源汽车换代问题

参考文献&#xff1a;百分点舆情中心《新能源汽车换代问题消费者情绪洞察报告》 行业背景 新能源汽车市场竞争加剧&#xff0c;车企不断推陈出新政府发布《汽车以旧换新补贴实施细则》&#xff0c;激励市场发展 *对汽车换代问题媒体关注度与网友讨论度高&#xff0c;正面声量…

电脑退域后系统黑屏

之前加入域时迁移了账号系统&#xff0c;导致退域后本地账号系统没了东西黑屏但能看到鼠标。也登不了域账号了一顿慌张&#xff08;操作如下&#xff09; 解决&#xff1a;又加回了域哈哈哈 重启电脑按F8进不去安全模式&#xff0c;找不到触发时间... winr打开运行&#xff0c;…

都说网络安全缺口那么大,但为何招聘数量却不多?总算明白了!

为啥网安领域缺口多达300多万人&#xff0c;但网安工程师也就是白帽黑客却很少&#xff0c;难道又是砖家在忽悠人&#xff1f; 原因主要为这三点: 首先是学校的原因&#xff0c;很多学校网络安全课程用的还都是十年前的老教材&#xff0c;教学脱离社会需求&#xff0c;实操技能…

【Python报错已解决】TypeError: expected Tensor as element 1 in argument 0, but got int

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

NHANES数据(复杂调查数据)亚组交互函数2.3版(P for interaction)发布---用于一键生成交互效应表

写在前面的话&#xff0c;本函数只支持NHANES数据(复杂调查数据)的逻辑回归和线性回归&#xff0c;其他类型均不支持&#xff0c;请注意甄别&#xff0c;电子产品&#xff0c;买错不能退换。 在SCI文章中&#xff0c;交互效应表格&#xff08;通常是表五&#xff09;能为文章锦…

多类别物体检测系统源码分享

多类别物体检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer V…

“领航猿1号” 正式更名为 “AGI舰长”

亲爱的朋友们&#xff0c;很高兴的告诉大家&#xff1a; 我各个平台的账号昵称正式 由“领航猿1号” 更名为 “AGI舰长” 为什么更名&#xff1a; 为了更好的更专注的为大家提供关于“AI大模型全栈”的分享&#xff0c;特此以 AI 为关键元素更名账号名称&#xff0c;大家可以…

企业内网知识问答库小程序源码系统 收录好+排名高 带完整的安装代码包以及搭建部署教程

系统概述 企业内网知识问答库小程序源码系统是一款集知识收集、整理、检索与分享于一体的综合解决方案。它基于现代Web技术和小程序框架开发&#xff0c;旨在为企业内部员工提供一个便捷、高效的知识交流平台。该系统不仅支持文本、图片、视频等多种形式的内容输入&#xff0c…

国际版短剧系统开发,海外多语言切换短剧APP源码部署上架

一、背景与需求 1. 背景介绍 随着全球化进程的加速和移动互联网的普及&#xff0c;短剧作为一种新型娱乐形式在全球范围内迅速走红。海外短剧系统是针对这一市场需求而开发的&#xff0c;旨在为全球观众提供高质量的短剧内容&#xff0c;并通过多样化的平台和服务&#xff0c…

禁止吸烟监测系统 基于图像处理的吸烟检测系统 YOLOv7

吸烟是引发火灾的重要原因之一。烟头在未熄灭的情况下&#xff0c;其表面温度可达200℃-300℃&#xff0c;中心温度甚至能高达700℃-800℃。在易燃、易爆的生产环境中&#xff0c;如化工厂、加油站、仓库等&#xff0c;一个小小的烟头就可能引发灾难性的火灾&#xff0c;造成巨…

【前端样式】Sweetalert2简单用法

1、 先安装sweetalert2库&#xff1a; npm install sweetalert2 2、引用SweetAlert2 库&#xff1a; import Swal from sweetalert2 &#xff1b; 3、代码拷过去直接去测试&#xff0c;vue代码 <template><div><el-button style"color: #C03639" clic…

【计算机网络 - 基础问题】每日 3 题(二十八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

Kafka学习笔记(一)Linux环境基于Zookeeper搭建Kafka集群、Kafka的架构

文章目录 1 Kafka简介1.1 什么是Kafka1.2 Kafka的应用场景1.3 Kafka的优势 2 搭建Kafka集群2.1 搭建Zookeeper集群2.1.1 上传并解压安装包2.1.2 修改配置文件2.2.3 创建dataDir和myid文件2.2.4 分发到另外两个节点2.2.5 修改node-02节点、node-03节点的配置文件和myid文件2.2.6…

【原创教程】西门子_部件手动模式FB块编辑

1、软件配置 ①软件配置 名称 版本 博图 V16 2、建立FB块 在编辑手动程序前应该建立手动程序的FB块&#xff0c;FB块的建立内容如下图所示 ①FB块的输入接口 Input:FB块的输入接口&#xff0c;将下拉列表中的数据应用于该FB块所编辑的程序中。 NO&#xff1a;当前部件…