Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement WPF-like MVVM in Qt/C++/QML?

Tags:

mvvm

wpf

qt

qml

I'm writing a proof of concept application, that is very simple. Basically it's composed of a UI where a list of "Note" type objects is displayed in a QML ListView.

I then have a few classes which is something along the lines:

#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

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

Finally a ViewModel that exposes Note to 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;
};

PLEASE DON'T MIND ANY C++ MISTAKES HERE and mind they are incomplete, it's not the point at this moment as I'm constantly adapting this as I learn.

The point where I'm struggling is, how to expose a list-like object to QML? The requirement is this list must be dynamic, one should be able to add, delete and modify the text of a note. When the list is modified by C++, it should also notify the UI (signal).

I tried QQmlListProperty, but couldn't figure a way of exposing it to QML. Then I read on another SO post this type can't be modified by QML (??), and I stumbled upon QAbstractItemModel.

Anyhow, can anyone point me to the right direction?

like image 912
johnildergleidisson Avatar asked Sep 06 '13 01:09

johnildergleidisson


Video Answer


1 Answers

The accepted answer is correct save for one detail. In MVVM you'd expose the ViewModel to QML, not the Model.

like image 174
reneb86 Avatar answered Oct 11 '22 18:10

reneb86