Qt5 Incorporar o object QWidget no QML

Estou usando o Qt5 beta e tentando incorporar um object baseado em QWidget no QML. O objective é usar o QML o máximo possível e usar apenas objects QWidget, nos quais o QML não faz o que eu preciso. Eu encontrei um link explicando como fazer isso para Qt4.7, mas eu não encontrei nenhuma informação explicando como fazer isso no Qt5.

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

O mesmo exemplo também está disponível na pasta de exemplos do Qt5 em:

exemplos \ qtquick1 \ declarativos \ cppextensions \ qwidgets

Infelizmente, este exemplo usa o QtQuick 1, em vez do QtQuick 2, e eu gostaria de usar os novos resources do Qt5. Eu realmente quero incorporar um widget qwt, mas como primeiro passo eu ficaria feliz em incorporar qualquer object simples baseado em QWidget.

Alguém pode me ajudar a obter o exemplo trabalhando em Qt5 / QtQuick 2?

O Qt Quick 2 usa um gráfico de cena para renderização eficiente na GPU. Infelizmente isso impossibilita a incorporação de widgets clássicos na cena. A abordagem antiga para embutir tais widgets com a ajuda de QGraphicsProxyWidget funciona apenas com o Qt Quick 1, porque internamente ele usa um QGraphicsView para todo o trabalho pesado e o QGraphicsProxyWidget é destinado a ser usado com ele.

A partir de agora, não há planos para permitir a inclusão de QWidgets clássicos no gráfico de cena que eu conheço. Acho improvável que isso mude, porque os conceitos do QPainter, a estrutura de pintura usada para os widgets clássicos e o novo gráfico de cena não funcionam bem um com o outro.

Há alguns esforços para desenvolver novos conjuntos de widgets especificamente adaptados às necessidades de QML, mas nenhum deles é tão poderoso e maduro quanto os widgets clássicos. Os mais proeminentes são os QML Quick Controls , incluídos no Qt desde a versão 5.1.

Se você realmente depende do QWT, meu conselho seria ficar com o Qt Quick 1.1 por enquanto. Ainda é empacotado com o Qt 5, provavelmente para casos como o seu. Dessa forma, você não aproveitará o novo gráfico de cena.

O que poderia ser feito é renderizar o widget para uma imagem e carregá-lo como texture.For interação alguém precisa para encaminhar events como mouseClick ou keyPressed do sceneGraph, traduzir para coordenadas de widget, passar, renderizar e fazer upload de textura novamente. Apenas uma ideia 🙂

A abordagem recomendada é ficar com um aplicativo baseado em QWidget e incorporar as partes do QML usando QWidget :: createWindowContainer.

Você pode incorporar o QWidget ao QML usando a class QQuickPaintedItem: http://doc.qt.io/qt-5/qquickpainteditem.html

O Qt5 tem um exemplo: http://doc.qt.io/qt-5/qtquick-customitems-painteditem-example.html

Você deve implementar um inerente de QQuickPaintedItem com atributo de widget privado, que você deseja incorporar. Forneça o método de pintura, que apenas processe o QtWidget e forneça o mouse e outro evento transmitindo da inheritance de QQuickPaintedItem para incorporar o QtWidget.

Há também QSG (API de gráfico de cena Qt), mas minha experiência com essa coisa não foi boa. Eu acredito que o indício em multithreading (realizando a renderização no segmento diferente (não o segmento de GUI do Qt um, no entanto, no Windows, isso não é verdade e tudo é feito no thread GUI principal).

Eu implementei a incorporação do QCustomPlot, aqui está o link: github.com/mosolovsa/qmlplot

Além da resposta de Julien – uma maneira simples de conseguir isso é usar o QQuickWidget para exibir a cena QML e, em seguida, adicionar um QWidget regular como um filho do QQuickWidget. Você também pode adicionar um QObject intermediário simples para ancorar o QWidget a um item na cena.

Por exemplo:

Em 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 _pWidget; QPointer _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()); } } }; 

Em 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("overlayItem")) new WidgetAnchor(pOwt, pOverlayItem); pqw->show(); return app.exec(); } 

A documentação declara que o uso do QQuickWidget possui vantagens sobre o QQuickView e o QWidget :: createWindowContainer, como nenhuma restrição na ordem de empilhamento, mas tem um ‘menor impacto no desempenho’.

Espero que ajude.

Aqui explicou como adicionar o QComboBox no layout baseado em QML. Pense que será um bom exemplo para o seu caso. (No Qt 5.9 implementado controle QML ComboBox nativo).

    Intereting Posts