QT5.在QML中嵌入Qwidget对象



我正在使用qt5 beta,并试图将基于Qwidget的对象嵌入QML。目的是尽可能多地使用QML,并且仅使用Qwidget对象,而QML无法完成我需要的事情。我找到了一个链接,解释了如何为QT4.7执行此操作,但是我还没有找到任何在QT5中进行此操作的信息。

http://doc.qt.digia.com/4.7/declarative-cppextensions-qwidgets.html

在QT5示例文件夹中也可以使用相同的示例:

示例 qtquick1 声明 cppextensions qwidgets

不幸的是,此示例使用Qtquick 1,而不是QTQUICK 2,我想使用QT5的新功能。我实际上想嵌入一个QWT小部件,但是作为第一步,我很乐意嵌入任何简单的基于Qwidget的对象。

任何人都可以帮助我在QT5/qtquick 2?

下完成示例

qt Quick 2使用场景图,以在GPU上有效渲染。不幸的是,这使得无法将经典小部件嵌入现场。借助QGraphicsProxyWidget嵌入此类小部件的旧方法仅适用于QT Quick 1,因为它在内部使用QGraphicsView用于所有重型举重,而QGraphicsProxyWidget则与其一起使用。

到目前为止,还没有计划将经典的Qwidgets嵌入我知道的场景图中。我认为这不太可能发生变化,因为QPainter的概念,用于经典小部件的绘画框架以及新场景图的彼此都不佳。

有一些努力来开发专门针对QML需求量身定制的新小部件集,但它们都不像经典小部件那样强大和成熟。最突出的是QML快速控件,自第5.1版以来与QT捆绑在一起。

如果您真的依赖QWT,我的建议是现在坚持使用QT Quick 1.1。它仍然与QT 5捆绑在一起,可能是像您这样的案件。这样,您就不会利用新场景图。

您可以使用qquickpainteditem类嵌入qwidget到qml:http://doc.qt.io/qt-5/qquickpainteditem.html

QT5有一个示例:http://doc.qt.io/qt-5/qtquick-customitems-painteditem-example.html

您应该使用要嵌入的私有小部件属性来实现QquickpaintedItem的固有。提供涂料方法,仅渲染qtwidget并提供鼠标和其他事件,从qquickpainteditem的继承传输到嵌入qtwidget。

还有QSG(QT场景图API),但是我对那件事的经验并不顺利。我相信多线程中的线索(在不同的线程中执行渲染(不是QT GUI线程,但是在Windows上都不为true,并且在主GUI线程中完成了所有操作)。

我已经实现了Qcustomplot的嵌入,此处的链接:github.com/mosolovsa/qmlplot

可以做的是将小部件渲染到图像并上传为纹理。对于某人需要转发诸如Mouseclick或从场景图中进行键盘的互动,将其转换为窗口小部件坐标,通过,再次渲染和上传纹理。只是一个想法:)

进一步到朱利安(Julien)的答案 - 实现此目的的一种简单方法是使用qquickwidget显示QML场景,然后在Qquickwidget的孩子中添加一个常规的Qwidget。您还可以添加一个简单的中间Qobject,将Qwidget固定到场景中的一个项目中。

例如:

在main.qml中:

Item {
    ... // layouts, extra items, what have you
        Item
        {
            objectName: "layoutItem"
            anchors.fill: parent
        }
    ... // more layouts, extra items, etc.
}

widgetanchor.h:

class WidgetAnchor: public QObject
{
    ptr<QWidget> _pWidget;
    QPointer<QQuickItem> _pQuickItem;
public:
    WidgetAnchor(QWidget* pWidget, QQuickItem* pItem)
        : QObject(pWidget), _pWidget(pWidget), _pQuickItem(pItem)
    {
        connect(_pQuickItem, &QQuickItem::xChanged, this, &WidgetAnchor::updateGeometry);
        connect(_pQuickItem, &QQuickItem::yChanged, this, &WidgetAnchor::updateGeometry);
        connect(_pQuickItem, &QQuickItem::widthChanged, this, &WidgetAnchor::updateGeometry);
        connect(_pQuickItem, &QQuickItem::heightChanged, this, &WidgetAnchor::updateGeometry);
        updateGeometry();
    }
private:
    void updateGeometry()
    {
        if (_pQuickItem)
        {
            QRectF r = _pQuickItem->mapRectToItem(0, QRectF(_pQuickItem->x(), _pQuickItem->y(), _pQuickItem->width(), _pQuickItem->height()));
            _pWidget->setGeometry(r.toRect());
        }
    }
};

在main.cpp中:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    auto pqw = new QQuickWidget;
    pqw->setSource(QUrl::fromLocalFile("main.qml"));
    pqw->setResizeMode(QQuickWidget::SizeRootObjectToView);
    pqw->setAttribute(Qt::WA_DeleteOnClose);
    auto pOwt = new MyWidget(pqw);
    if (auto pOverlayItem = pqw->rootObject()->findChild<QQuickItem*>("overlayItem"))
        new WidgetAnchor(pOwt, pOverlayItem);
    pqw->show();
    return app.exec();
}

文档指出,使用Qquickwidget比Qquickview和Qwidget :: createWindowContainer具有优势,例如对堆叠顺序没有限制,但具有"次要性能命中"。

希望会有所帮助。

推荐的方法是使用基于Qwidget的应用程序,并使用Qwidget :: createWindowContainer嵌入QML零件。

相关内容

  • 没有找到相关文章

最新更新