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 WId
s 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.
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
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.
To make this platform independent, you have to write a (public) function in which you test for the platform using preprocessor #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.
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
}