2017-08-22 1 views
0

J'ai QAbstractListModel en C++ code et connecté avec QML GridView de Butons au moyen deQML: Signal GridView.onReloaded

QQmlApplicationEngine engine; 
QQmlContext* context = engine.rootContext(); 
context->setContextProperty("keyboardModel", _keyboardModel); 

L'objectif principal est d'obtenir les coordonnées globales de boutons dans le code C++. À cet effet, je trouve ces boutons avec la fonction QQuickItem::childItems() et obtenir les coordonnées finales avec mapToGlobal().

Maintenant, quand j'ai changé le modèle C++, qml GridView a changé aussi. Mais, je ne peux pas attraper moment, quand arborescence QQuickItem hiérarchique entièrement actualisé (Il a besoin pour le bon fonctionnement QQuickItem::childItems())

Les signaux de GridView sur Ajouter, sur Supprimer ne fonctionne pas, lorsque le nouveau modèle a la même quantité d'éléments. Le signal de GridView onModelChanged s'est déclenché seulement quand j'ai connecté un autre modèle, pas quand j'ai changé celui-ci.

Existe-t-il un signal à reconnaître lorsque l'arborescence QQuickItem hiérarchique est entièrement actualisée? Ou existe-t-il une autre méthode pour obtenir dynamiquement les coordonnées globales de l'objet Qml?

+0

Pourquoi voudriez-vous avoir les coordonnées du bouton en C++? Habituellement, vous avez le modèle de données en C++ et la vue en QML. Le modèle de données doit être agnostique en vue. De plus, vous * pouvez * mais * ne devriez pas * interroger QML à partir de C++. Laissez le côté QML dire au C++ ce que C++ doit savoir. – derM

+0

Je devrais l'envoyer à une autre application. – Nikxp

+0

Un 'GridView' utilise une instanciation dynamique, ce qui signifie que vous ne pouvez pas être sûr que tous les' Boutons 'définis dans votre modèle seront instanciés à chaque instant.De plus, le 'GridView' est un' Flickable' de sorte que les positions vont changer, lors de l'effleurement, où vous aurez beaucoup de changements pour des tonnes d'objets. Comment allez-vous (conceptuellement) gérer cela? C'est parce que dans votre question, vous ne gérez que * suppression et ajout * au lieu de feuilleter. Si c'est plutôt statique, vous devriez considérer un 'Repeater' et un' Grid' à la place. – derM

Répondre

0

Il n'y a pas de signal pour lorsque le GridView est reconstruit

Cependant, le GridView a une propriété moving et le signal movementEnded

j'aurais chaque Button dans votre GridView connecté à ce signal. En outre gérer le Component.onCompleted du Button. Ce signal est renvoyé lorsque le Button est (re) créé.

Maintenant, vous exposer un Q_INVOCABLE dans un objet C++, qui prend les informations requises en tant que paramètres. Disons, sa signature est

void reportPosition(QString name, int x, int y) 

Maintenant, dans le Button vous avez:

id: myGridView 
delegate: Button { 
    Component.onCompleted: { 
     var p = mapToGlobal(x, y) 
     myCppObject.reportPosition(objectname, p.x, p.y) 
    } 
    Connections { 
     target: myGridView 
     onMovementEnded: { 
     var p = mapToGlobal(x, y) 
     myCppObject.reportPosition(objectname, p.x, p.y) 
    } 
} 

Avec ce nous avons réalisé:

  • C++ arrive à connaître la position de tous les boutons créés lorsque leur le mouvement est terminé
  • C++ apprend à connaître la position de tous les boutons nouvellement créés lors de la création (garde-le avec if (!moving) [...] si vous ne voulez pas la position des boutons nouvellement créés, quand ils sont en mouvement)
  • Vous n'avez pas besoin d'interroger QML de C++, mais ont rapport QML à

C++ Ceci est juste un aperçu de l'idée. Je n'ai pas les moyens de le tester en ce moment, donc il pourrait y avoir des erreurs.

+0

mapToGlobal est une fonction C++. Je l'ai utilisé, mais seulement, quand j'ai déjà le pointeur QQuickItem sur le bouton. Comme je sais, il n'y a pas de façon élégante et claire de le faire en qml (par exemple cette solution est sale, comme l'a dit l'auteur https://stackoverflow.com/questions/21454393/qml-screen-coordinates-of-component) – Nikxp

+0

['mapToGlobal()'] (http://doc.qt.io/qt-5/qml-qtquick-item.html#mapToGlobal-method) est une fonction C++ exposée à QML par chaque 'Item' – derM

+0

Bien sûr vous peut également appeler la fonction et passer le bouton lui-même à C++ si vous préférez avoir un pointeur d'objet. C'est entièrement à vous! – derM