Qt5. Intégrer l'objet QWidget dans QML

j'utilise Qt5 beta et j'essaie d'intégrer un objet basé sur QWidget dans QML. Le but est d'utiliser QML autant que possible, et de n'utiliser que les objets QWidget où QML ne fait pas ce dont j'ai besoin. J'ai trouvé un lien expliquant comment faire pour Qt4.7, mais je n'ai pas trouvé d'information expliquant comment faire en Qt5.

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

sur Le même exemple est également disponible dans le dossier exemples Qt5 en vertu de l':

examplesqtquick1declarativeCPP extensionsqwidgets

malheureusement, cet exemple utilise QtQuick 1, plutôt que QtQuick 2, et j'aimerais utiliser les nouvelles fonctionnalités de Qt5. En fait, je veux intégrer un widget qwt, mais dans un premier temps, je serais heureux d'intégrer n'importe quel objet simple basé sur QWidget.

Quelqu'un peut-il m'aider à obtenir L'exemple de travail sous Qt5 / QtQuick 2 ?

28
demandé sur eatyourgreens 2012-10-22 19:14:17

6 réponses

Qt Quick 2 utilise un graphe de scène pour un rendu efficace sur le GPU. Malheureusement, cela rend impossible d'intégrer des widgets classiques dans la scène. L'ancienne approche pour incorporer ces widgets à l'aide de QGraphicsProxyWidget ne fonctionne qu'avec Qt Quick 1, car en interne il utilise un QGraphicsView pour tout le levage lourd et QGraphicsProxyWidget est destiné à être utilisé avec elle.

à ce jour, il n'y a pas de plans pour permettre l'intégration des QWidgets classiques dans le graphe de scène que je connais. Je pense que c'est plutôt peu probable de changer, parce que les concepts de QPainter, le cadre de peinture utilisé pour les widgets classiques, et le nouveau graphe de scène ne joue pas bien l'un avec l'autre.

il y a quelques efforts pour développer de nouveaux ensembles de widgets spécifiquement adaptés aux besoins de QML, mais aucun d'eux n'est aussi puissant et mature que les widgets classiques. Les plus importantes sont l' QML des Contrôles Rapides, fourni avec Qt depuis la version 5.1.

si vous dépendez vraiment de QWT my le conseil serait de s'en tenir à Qt Quick 1.1 Pour l'instant. Il est toujours livré avec Qt 5, probablement pour des affaires comme la vôtre. De cette façon, vous ne prenez pas avantage de la nouvelle scène graphique.

31
répondu sebasgo 2015-06-08 08:43:10

ce qui pourrait être fait est de rendre le widget à une image et de télécharger sous forme de texture.Pour l'interaction, quelqu'un doit transmettre des événements comme mouseClick ou keyPressed à partir du sceneGraph, traduire en coordonnées widget, transmettre, rendre et télécharger la texture à nouveau. Juste une idée :)

7
répondu Sebastian 2012-11-29 17:21:35

l'approche recommandée est de rester avec une application basée sur QWidget et d'intégrer les parties QML en utilisant QWidget:: createWindowContainer.

5
répondu Julian 2013-11-09 12:55:20

vous pouvez intégrer QWidget à QML en utilisant la classe QQuickPaintedItem: http://doc.qt.io/qt-5/qquickpainteditem.html

Qt5 a un exemple: http://doc.qt.io/qt-5/qtquick-customitems-painteditem-example.html

vous devriez implémenter un inhérent de QQuickPaintedItem avec l'attribut widget privé, que vous voulez intégrer. Fournit la méthode paint, qui rend juste le QtWidget et fournit la souris et d'autres événements transmettant de l'héritage de QQuickPaintedItem to embed QtWidget.

il y a aussi QSG (QT scene graph API), mais mon expérience avec cette chose n'était pas facile. Je crois que l'indice dans multithreading (effectuer le rendu dans le fil différent (pas le fil Qt GUI Un, cependant sur Windows ce n'est pas vrai et tout est fait dans le fil GUI principal).

j'ai implémenté l'intégration de QCustomPlot, voici le lien: github.com/mosolovsa/qmlplot

3
répondu Mosolov Sergey 2017-03-21 15:57:19

suite à la réponse de Julien - une façon simple d'y parvenir est d'utiliser QQuickWidget pour afficher la scène QML, puis d'ajouter un QWidget régulier comme un enfant du QQuickWidget. Vous pouvez également ajouter un simple QObject intermédiaire pour ancrer le QWidget à un élément de la scène.

par exemple:

Dans le 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());
        }
    }
};

Dans le main.rpc:

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();
}

la documentation indique que L'utilisation de QQuickWidget a avantages par rapport à QQuickView et QWidget::createWindowContainer, comme aucune restriction sur l'ordre de cumul, mais a un "succès de performance mineur".

j'Espère que vous aide.

0
répondu NickD2039 2017-07-25 05:33:58

Ici a expliqué comment ajouter QComboBox sur la mise en page basée sur QML. Je pense que ce sera un bon exemple pour votre cas. (Dans Qt 5.9, mise en œuvre du contrôle natif de ComboBox QML).

0
répondu stanislav888 2017-11-24 11:57:28