The trick is to get targetWindowId and feed that to QScreen grabWindow. This will give you QPixmap format which is easily converted into OpenCV cv::Mat.
For that I picked a class which is called private in Qt source code because it is not part of their API.
class QCapturableWindowPrivate : public QSharedData {
public:
using Id = size_t;
QString description;
Id id = 0;
static const QCapturableWindowPrivate *handle(const QCapturableWindow &window)
{
return window.d.get();
}
QCapturableWindow create() { return QCapturableWindow(this); }
};
class Screenshot {
public:
Screenshot(const QString& windowName);
void displayLiveView();
private:
QPixmap grabWindow();
WId targetWindowId = 0;
QWindowCapture windowCapture;
};
Screenshot::Screenshot(const QString& windowName) {
WindowListModel windowListModel;
windowListModel.populate();
QCapturableWindow targetWindow; // Window we are looking for
bool windowFound = false;
for (int i = 0; i < windowListModel.rowCount(); i++) {
QModelIndex index = windowListModel.index(i);
if (index.isValid()) {
QString currentWindowDesc = windowListModel.data(index, Qt::DisplayRole).toString();
if (currentWindowDesc.contains(windowName)) {
targetWindow = windowListModel.window(index);
windowFound = true;
break;
}
}
}
if (!windowFound) {
qDebug() << "Window not found!";
return;
}
windowCapture.setWindow(targetWindow);
auto handle = QCapturableWindowPrivate::handle(targetWindow);
targetWindowId = handle ? handle->id : 0;
}
QPixmap Screenshot::grabWindow() {
if (targetWindowId == 0) return QPixmap();
QScreen *screen = QGuiApplication::primaryScreen();
if (!screen) return QPixmap();
return screen->grabWindow(targetWindowId);
}
void Screenshot::displayLiveView() {
while (true) {
QPixmap pixmap = grabWindow();
if (pixmap.isNull()) {
qDebug() << "Failed to capture the window.";
continue;
}
QImage image = pixmap.toImage();
cv::Mat mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
cv::imshow("Live View", mat);
if (cv::waitKey(30) == 27) {
break;
}
}
}
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// Print available windows
WindowListModel model;
for (int i = 0; i < model.rowCount(); i++) {
QModelIndex index = model.index(i);
if (index.isValid()) {
QString windowDesc = model.data(index, Qt::DisplayRole).toString();
std::cout << i + 1 << ". " << windowDesc.toStdString() << std::endl;
}
}
Screenshot screenshot("Settings"); //The name of the window from the printed list
screenshot.displayLiveView();
return 0;
}