2013-09-06 17 views
8

Ich schreibe eine Proof-of-Concept-Anwendung, die sehr einfach ist. Im Grunde besteht es aus einer Benutzeroberfläche, in der eine Liste von "Notiz" -Typ-Objekten in einer QML-ListView angezeigt wird.Wie implementiert man WPF-ähnliche MVVM in Qt/C++/QML?

ich dann ein paar Klassen haben, die etwas entlang der Linien ist:

#ifndef NOTE_H 
#define NOTE_H 

#include <string> 

using namespace std; 
class Note 
{ 
public: 
    Note(QObject* parent = 0) 
     : QObject(parent) 
    { 

    } 

    Note(const int id, const string& text) 
     : _id(id), _text(text) 
    { 
    } 

    int id() 
    { 
     return _id; 
    } 

    const string text() 
    { 
     return _text; 
    } 

    void setText(string newText) 
    { 
     _text = newText; 
    } 

private: 
    int _id; 
    string _text; 
}; 

#endif // NOTE_H 

Dann wird ein Repository:

class NoteRepository : public Repository<Note> 
{ 
public: 
    NoteRepository(); 
    ~NoteRepository(); 

    virtual shared_ptr<Note> getOne(const int id); 
    virtual const unique_ptr<vector<Note>> getAll(); 
    virtual void add(shared_ptr<Note> item); 
private: 
    map<int, shared_ptr<Note>> _cachedObjects; 
}; 

Endlich ein Ansichtsmodell, die Hinweis auf QML aussetzt

class MainViewModel : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(QQmlListProperty<Note> notes READ notes NOTIFY notesChanged) 
    Q_PROPERTY(int count READ count() NOTIFY countChanged) 
public: 
    MainViewModel(QObject *newParent = 0); 
    int count(); 
    QQmlListProperty<Note> notes(); 
signals: 
    void notesChanged(); 
    void countChanged(); 
public slots: 
private: 
    std::shared_ptr<UnitOfWork> _unitOfWork; 
    static void appendNote(QQmlListProperty<Note> *list, Note *note); 
    QList<Note*> _notes; 
}; 

BITTE BEACHTEN SIE KEINE C++ FEHLER HIER und beachten Sie, dass sie unvollständig sind, Es ist nicht der Punkt in diesem Moment, da ich mich ständig daran anpasse, wie ich lerne.

Der Punkt, an dem ich kämpfe, ist, wie man ein listenähnliches Objekt an QML exponiert? Die Voraussetzung ist, dass diese Liste dynamisch sein muss, man sollte den Text einer Notiz hinzufügen, löschen und ändern können. Wenn die Liste von C++ geändert wird, sollte sie auch die UI (Signal) benachrichtigen.

Ich habe QQmlListProperty ausprobiert, konnte aber keine Möglichkeit finden, sie QML auszusetzen. Dann lese ich auf einem anderen SO-Post diesen Typ kann nicht von QML (??) geändert werden, und ich stolperte über QAbstractItemModel.

Wie auch immer, kann mir jemand in die richtige Richtung zeigen?

+1

'QAbstractItemModel' sollte die richtige Richtung dafür sein. Sie können weitere Informationen hier finden: http://qt-project.org/doc/qt-5.1/qtquick/qtquick-modelviewsdata-cppmodels.html – koopajah

Antwort

8

Ich habe ein ziemlich vollständiges Beispiel in another answer gepostet.

Das allgemeine Verfahren ist:

  1. ein Modell erstellen, das von QAbstractItemModel ableitet. Sie können alle bereits von Qt bereitgestellten Modelle wiederverwenden, z. B. QStringListModel.

  2. Expose es zu QML. Z.B. Verwenden Sie setContextProperty() von QML Engine rootContext().

  3. Die Rollen des Modells sind im Kontext des Delegaten in QML sichtbar. Qt bietet die Standardzuordnung zwischen Namen und Rollen für die DisplayRole (display) und EditRole (edit) in einer Standardimplementierung von roleNames().

    delegate: Component { 
        TextInput { 
         width: view.width // assuming that view is the id of the view object 
         text: edit // "edit" role of the model, to break the binding loop 
         onTextChanged: model.display = text // "display" role of the model 
        } 
    } 
    
  4. können Sie Zwischenviewmodel schaffen, falls erforderlich, durch Proxy-Modelle zwischen den Ansichten Befestigung und den Back-End-Modellen. Sie können von QAbstractProxyModel oder einer seiner Unterklassen ableiten.

Verwandte Themen