2013-09-06 21 views
8

Piszę aplikację sprawdzającą koncepcję, która jest bardzo prosta. Zasadniczo składa się z interfejsu użytkownika, w którym lista obiektów typu "Uwaga" jest wyświetlana w widoku listy QML.Jak wdrożyć MVVM podobną do WPF w Qt/C++/QML?

Mam następnie kilka klas, które jest coś wzdłuż linii:

#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 

Następnie repozytorium:

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

Wreszcie ViewModel że naraża Uwaga do QML

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

PROSZĘ NIE UMIEŚCIĆ ŻADNYCH WIADOMOŚCI C++ TUTAJ i uważać, że są niepełne, W tej chwili nie o to chodzi, ponieważ ciągle się do tego dostosowuję, kiedy się uczę.

Punkt, w którym walczę, to jak odsłonić obiekt podobny do listy do QML? Wymaganie jest takie, że lista musi być dynamiczna, należy umieć dodawać, usuwać i modyfikować tekst notatki. Gdy lista jest modyfikowana przez C++, powinna również powiadomić UI (sygnał).

Próbowałem QQmlListProperty, ale nie mogłem wymyślić sposobu na ujawnienie go w QML. Potem czytam na innym stanowisku SO tego typu nie może być modyfikowany przez QML (??) i natknąłem się na QAbstractItemModel.

W każdym razie, czy ktoś może wskazać mi właściwy kierunek?

+1

'QAbstractItemModel' powinien być właściwym kierunkiem dla tego. Możesz znaleźć więcej informacji tutaj: http://qt-project.org/doc/qt-5.1/qtquick/qtquick-modelviewsdata-cppmodels.html – koopajah

Odpowiedz

8

Opublikowałem dość kompletny przykład w another answer.

Ogólna procedura:

  1. Tworzenie modelu, który wynika z QAbstractItemModel. Możesz ponownie użyć dowolnego z modeli już dostarczonych przez Qt, na przykład QStringListModel.

  2. Narazić go na QML. Na przykład. użyj setContextProperty() z QML Engine's rootContext().

  3. Role modelu widoczne są w kontekście delegata w QML. Qt zapewnia domyślne odwzorowanie między nazwami i rolami dla DisplayRole (display) i EditRole (edit) w domyślnej implementacji 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. Można tworzyć ViewModels pośrednich, w razie potrzeby, poprzez dołączenie modeli proxy między widokami i modeli wspierających. Możesz wywodzić się z QAbstractProxyModel lub jednej z jej podklas.