【问题标题】:QQuickWidget: grabToImage: item's window is not visibleQQuickWidget:grabToImage:项目的窗口不可见
【发布时间】:2025-12-27 00:10:16
【问题描述】:

我在尝试使用 Item::grabToImage() qml 方法时遇到问题。 无论我指向哪个项目,它总是说以下错误:

grabToImage:项目的窗口不可见

我也尝试过使用名为 rect 的根/*项目,但它不起作用。

我的目标:我想捕捉一个矩形大小的图像,上面有地图图块和多边形绘制

下面是一个最小的可重现示例

import QtQml 2.2
import QtLocation 5.9
import QtPositioning 5.9
import QtQuick 2.0
import QtQuick.Controls 2.4

Item {
    id: rect
    width: 1024
    height: 768

    visible: true

    Plugin {
        id: mapPlugin
        name: "osm"
    }

    Map {
        id: map
        enabled: true
        visible: true
        parent: rect
        gesture.enabled: true
        anchors.fill: parent
        plugin: mapPlugin
        zoomLevel: 14
        activeMapType: supportedMapTypes[3]
    }

    Item {
        anchors.bottom: parent.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: 10
        height: 40

        Button {
            id: saveToDisk
            text: qsTr("Pick")
            onClicked: {
                map.grabToImage(function (result) {
                    console.log('saving to disk..')
                    result.saveToFile("pick.png")
                })
            }
        }
    }
}
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQuickWidgets/QQuickWidget>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);

    QQuickWidget *q = new QQuickWidget;
    q->setResizeMode(QQuickWidget::SizeRootObjectToView);
    q->setSource(QUrl("main.qml"));
    q->show();

    return app.exec();
}

【问题讨论】:

  • 我会关注上一条评论中的 minimal 这个词。我们应该如何处理所有这些不相关的代码?请创建重现错误的工作代码并在此处重新发布。
  • 抱歉,添加了一个最小的可重现示例:)

标签: qt qml qt5 qquickwidget


【解决方案1】:

QQuickWidget 的绘画策略是创建一个屏幕外的 QQuickWindow,它可以渲染 QML,从那里截取屏幕截图并绘制到小部件上。以上限制了grabToImage()的使用,因为这种方法要求项目的QQuickWindow是可见的。

解决方法是使用QQuickView + QWidget::createWindowContainer():

#include <QApplication>
#include <QWidget>
#include <QQuickView>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);

    QQuickView *q = new QQuickView;
    q->setResizeMode(QQuickView::SizeRootObjectToView);
    q->setSource(QUrl("main.qml"));

    QWidget * container = QWidget::createWindowContainer(q);
    container->show();

    return app.exec();
}

【讨论】:

  • 解决方案完美无瑕。但我还有一个问题:是否可以渲染整个 qml 源文件但 qquickwindow 不可见?我注意到有一个与此相关的主题:*.com/questions/17146747/… 这种解决方案可能吗?实现这一目标的最佳方法是什么?我需要的是使用 QML 执行后台任务,例如渲染地图和截取地图部分(矩形)的屏幕截图。
  • 好的,我想我可以在这里问,因为这更像是一个个人问题。
  • @AlexSoletti 个人?我不认为这个问题是个人的。您的问题(在屏幕外记录 QML 的某些部分)与您的原始问题(记录在 QQuickWidget 中呈现的项目)相去甚远,因此建议您创建另一个问题,以便社区的更多成员可以帮助您。
  • *.com/questions/59503641/… 这里有新问题,你
最近更新 更多