我正在使用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零件。