获取QT中的窗口WI列表

时间:2020-12-31 19:18:37

I'm writing a library in QT which will take screenshots of arbitrary external windows. I know how to take the screenshot using QScreen::grabWindow(), but this takes as an argument a WId, and I would like to know if there is a way to get a list of WIds for all windows on the screen and/or desktop (or something similar, such as getting a WId for a specific window using a title name), via QT. I am aware that I can do this in a platform dependent way, such as EnumWindows in Windows, but I was hoping to keep it cross-platform within QT if possible.

我正在QT中编写一个库,它将截取任意外部窗口的截图。我知道如何使用QScreen :: grabWindow()获取屏幕截图,但这需要一个参数作为一个参数,我想知道是否有办法获取屏幕上所有窗口的WId列表和/或桌面(或类似的东西,例如使用标题名称获取特定窗口的WId),通过QT。我知道我可以以平台相关的方式执行此操作,例如Windows中的EnumWindows,但我希望尽可能在QT内保持跨平台。

1 个解决方案

#1


4  

This isn't possible with Qt. If you want your library to be platform independent, you need to write a code for each platform you want to support.

Qt不可能做到这一点。如果您希望库与平台无关,则需要为要支持的每个平台编写代码。

To make this platform independent, you have to write a (public) function in which you test for the platform using preprocessor #if:

要使此平*立,您必须编写一个(公共)函数,在该函数中使用预处理器#if测试平台:

#ifdef __unix__
    // call unix specific code
#elseif ...
    // other platforms
#else
#error Platform not supported!
#endif

For the unix specific code, you need to use xlib, which manages the windows in a tree. From the following code, you will get ALL windows, and in X11 there are a lot of invisible windows and windows which you don't think that they are separate windows. So you definitely have to filter the results, but this depends on which window types you want to have.

对于unix特定代码,您需要使用xlib来管理树中的窗口。从下面的代码中,您将获得所有窗口,并且在X11中有许多不可见的窗口和窗口,您不认为它们是单独的窗口。所以你肯定要过滤结果,但这取决于你想要的窗口类型。

Take this code as a start:

以此代码为开头:

#include <X11/Xlib.h>

// Window is a type in Xlib.h
QList<Window> listXWindowsRecursive(Display *disp, Window w)
{
    Window root;
    Window parent;
    Window *children;
    unsigned int childrenCount;

    QList<Window> windows;
    if(XQueryTree(disp, w, &root, &parent, &children, &childrenCount))
    {
        for(unsigned int i = 0; i < childrenCount; ++i)
        {
            windows << children[i];
            windows << listXWindowsRecursive(disp, children[i]);
        }
        XFree(children);
    }
    return windows;
}

Display *disp = XOpenDisplay(":0.0");
Window rootWin = XDefaultRootWindow(disp);
QList<Window> windows = listXWindowsRecursive(disp, rootWin);

foreach(Window win, windows)
{
    // Enumerate through all windows
}

#1


4  

This isn't possible with Qt. If you want your library to be platform independent, you need to write a code for each platform you want to support.

Qt不可能做到这一点。如果您希望库与平台无关,则需要为要支持的每个平台编写代码。

To make this platform independent, you have to write a (public) function in which you test for the platform using preprocessor #if:

要使此平*立,您必须编写一个(公共)函数,在该函数中使用预处理器#if测试平台:

#ifdef __unix__
    // call unix specific code
#elseif ...
    // other platforms
#else
#error Platform not supported!
#endif

For the unix specific code, you need to use xlib, which manages the windows in a tree. From the following code, you will get ALL windows, and in X11 there are a lot of invisible windows and windows which you don't think that they are separate windows. So you definitely have to filter the results, but this depends on which window types you want to have.

对于unix特定代码,您需要使用xlib来管理树中的窗口。从下面的代码中,您将获得所有窗口,并且在X11中有许多不可见的窗口和窗口,您不认为它们是单独的窗口。所以你肯定要过滤结果,但这取决于你想要的窗口类型。

Take this code as a start:

以此代码为开头:

#include <X11/Xlib.h>

// Window is a type in Xlib.h
QList<Window> listXWindowsRecursive(Display *disp, Window w)
{
    Window root;
    Window parent;
    Window *children;
    unsigned int childrenCount;

    QList<Window> windows;
    if(XQueryTree(disp, w, &root, &parent, &children, &childrenCount))
    {
        for(unsigned int i = 0; i < childrenCount; ++i)
        {
            windows << children[i];
            windows << listXWindowsRecursive(disp, children[i]);
        }
        XFree(children);
    }
    return windows;
}

Display *disp = XOpenDisplay(":0.0");
Window rootWin = XDefaultRootWindow(disp);
QList<Window> windows = listXWindowsRecursive(disp, rootWin);

foreach(Window win, windows)
{
    // Enumerate through all windows
}