2017-08-22 4 views
0

Ich habe QAbstractListModel in C++ Code und verbunden mit qml Gridview von Butons mittelsQML: GridView.onReloaded Signal

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

Das Hauptziel ist die globalen Koordinaten von Buttons in C++ Code erhalten. Zu diesem Zweck finde ich diese Tasten mit QQuickItem::childItems() Funktion und erhalten endgültige Koordinaten mit mapToGlobal().

Nun, wenn ich C++ - Modell geändert, qml GridView auch geändert. Aber, ich kann nicht Moment, wenn hierarchische QQuickItem Baum vollständig aufgefrischt (benötigt für die korrekte Arbeit QQuickItem::childItems())

GridView Signale onAdd, auf Entfernen funktioniert nicht, wenn das neue Modell hat die gleiche Anzahl von Elementen. GridViews Signal onModelChanged hat nur ausgelöst, wenn ich ein anderes Modell angeschlossen habe, nicht wenn ich dieses geändert habe.

Gibt es ein Signal zur Erkennung, wenn der hierarchische QQuickItem-Baum vollständig aktualisiert wurde? Oder gibt es eine andere Methode, um die globalen Koordinaten von Qmls Objekt dynamisch zu erhalten?

+0

Warum möchten Sie die Koordinaten des Buttons in C++ haben? Normalerweise haben Sie das Datenmodell in C++ und die Ansicht in QML. Das Datenmodell sollte Sicht agnostisch sein. Weiter können * Sie * aber * QML nicht aus C++ abfragen. Lassen Sie die QML-Seite der C++ Seite mitteilen, was C++ wissen muss. – derM

+0

Ich sollte es an eine andere App senden. – Nikxp

+0

Eine 'GridView' verwendet dynamische Instanziierung, was bedeutet, dass Sie nicht sicher sein können, dass alle in Ihrem Modell definierten' Buttons' zu jedem Zeitpunkt instanziiert werden.Außerdem ist das 'GridView' ein' Flickable', so dass sich die Positionen beim Blättern ändern, wo es viele Änderungen für Tonnen von Objekten gibt. Wie werden Sie (konzeptionell) damit umgehen? Das liegt daran, dass Sie in Ihrer Frage nur * Entfernen und Hinzufügen * handhaben, anstatt herumzublättern. Wenn es eher statisch ist, sollten Sie stattdessen einen 'Repeater' und ein' Grid' betrachten. – derM

Antwort

0

Es gibt kein Signal für wenn das Gridview

wieder aufgebaut wird jedoch die GridView eine Eigenschaft hat moving und das Signal movementEnded

Ich würde jede Button in Ihrem GridView auf dieses Signal angeschlossen haben. Weiter behandeln die Component.onCompleted der Button. Dieses Signal wird ausgelöst, wenn die Button (neu) erstellt wird.

Jetzt setzen Sie ein Q_INVOCABLE in einem C++ Objekt frei, das die erforderlichen Informationen als Parameter übernimmt. Lassen Sie uns sagen, seine Unterschrift ist

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

Jetzt in der Button Sie haben:

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

Damit wir erreicht:

  • C++ wird die Position aller erstellten Buttons wissen, wann ihre Bewegung ist beendet
  • C++ lernt die Position aller neu erstellten Schaltflächen bei der Erstellung kennen (bewachen Sie sie mit if (!moving) [...], wenn Sie nicht die Position des neu geschaffenen Buttons wollen, wenn sie sich bewegen)
  • Sie brauchen nicht QML von C++ abzufragen, sondern haben QML Bericht zu C++

Dies ist nur ein Umriss der Idee. Ich habe nicht die Mittel, um es jetzt zu testen, also könnte es Fehler geben.

+0

mapToGlobal ist eine C++ - Funktion. Ich habe es benutzt, aber nur, wenn ich bereits QQuickItem-Zeiger auf Button habe. Wie ich weiß, gibt es keinen eleganten und klaren Weg, es in qml (zum Beispiel diese Lösung ist schmutzig, wie der Autor sagte 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) ist eine C++ - Funktion, die QML von jedem 'Item' ausgesetzt ist. – derM

+0

Natürlich Sie Sie können die Funktion auch aufrufen und den Button selbst an C++ übergeben, wenn Sie einen Objektzeiger bevorzugen. Das liegt ganz bei Ihnen! – derM

Verwandte Themen