Results 1 to 8 of 8

Thread: Modify c++ model data from QML Repeater

  1. #1
    Join Date
    Dec 2010
    Location
    Veszprém, Hungary
    Posts
    34
    Thanks
    2
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Modify c++ model data from QML Repeater

    Hi all!

    I would like to create something similar to the corkboard qml example. On a screen I have some items, which I can move, resize, rotate, and I can store these properties.

    I created a model inherited from QAbstractListModel on C++ side. It populates data well.

    On the QML side I show it in a Repeater, like this:
    Qt Code:
    1. Repeater {
    2. id: myRepeater
    3. model: dayScreenModel
    4. DayScreenEntry {
    5. x: position.x
    6. y: position.y
    7. text: title
    8. }
    To copy to clipboard, switch view to plain text mode 

    position, title, size, rotation comes from the C++ model.

    It works fine.

    But how can I achieve modification of these data?

    I found a way:
    in the model, created a public slot:
    void updateData(int index, QString role, QVariant value);

    and, in the DayScreenEntry.qml I can call like this:
    myRepeater.model.updateData(index, "title", "NewTitle")

    I can refresh the data in code, and it populates also to the qml side, shows the changes.

    But, I have some problems with it:
    - it's not 'elegant' - Is it possible somehow to call the 'setData' function of the model?
    - on QML side, i have to write the model name in the delegate - I can use it only for this model, have to know the model name.

    Do You know any other way to get this stuff working?

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Modify c++ model data from QML Repeater

    Since the delegate is a component, it should be possible to have it contain an item that allows you to edit the content it displays (like the TextEdit element). If you bind the model's property to a property that is editable by the component, there is a good chance the change will be propagated to the model.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Dec 2010
    Location
    Veszprém, Hungary
    Posts
    34
    Thanks
    2
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Modify c++ model data from QML Repeater

    Hello!

    Thank You for your reply. I want expect what you write. But I don't know, how...

    I attach a simple example.
    The interesting part is in the qml file's mousearea section. I can reach the index, and the title also... But I cannot change the title
    Maybe only I forgot to set a flag or something like this.
    I think, that 'setData' should be called somehow as when the data populates from the model to the view - it's achieved by the 'data' function.
    QmlModel.zip

    main.cpp
    Qt Code:
    1. #include <QApplication>
    2. #include <QMessageBox>
    3.  
    4. #include "mainwidget.h"
    5.  
    6. int main(int argc, char** argv)
    7. {
    8. QApplication a (argc, argv);
    9.  
    10. MainWidget* mainWidget=new MainWidget();
    11. mainWidget->show();
    12. int r=0;
    13. try
    14. {
    15. r=a.exec();
    16. }catch (...)
    17. {
    18. QMessageBox::critical(NULL, QObject::tr("Error"), QObject::tr("Critical error - Unhandled exception in the application!"));
    19. r=-1;
    20. }
    21. delete mainWidget;
    22. return r;
    23. }
    To copy to clipboard, switch view to plain text mode 

    mainwidget.h
    Qt Code:
    1. #ifndef MAINWIDGET_H
    2. #define MAINWIDGET_H
    3.  
    4. #include <QtDeclarative/QDeclarativeView>
    5. #include "dummymodel.h"
    6.  
    7.  
    8. class MainWidget : public QDeclarativeView
    9. {
    10. Q_OBJECT;
    11. public:
    12. MainWidget(QWidget* parent=0);
    13. ~MainWidget();
    14. public slots:
    15.  
    16.  
    17. private:
    18. QDeclarativeContext* m_context;
    19. DummyModel model;
    20.  
    21. };
    22.  
    23. #endif // MAINWIDGET_H
    To copy to clipboard, switch view to plain text mode 

    mainwidget.cpp
    Qt Code:
    1. #include "mainwidget.h"
    2.  
    3. #include <QtDeclarative>
    4. #include <QDeclarativeContext>
    5.  
    6. MainWidget::MainWidget(QWidget* parent) : QDeclarativeView(parent)
    7. {
    8. setResizeMode(QDeclarativeView::SizeRootObjectToView);
    9. setMinimumSize(300,300);
    10.  
    11. m_context=rootContext();
    12. m_context->setContextProperty("dummyModel", &model);
    13. setSource(QUrl("qml/qmlModel/main.qml"));
    14. }
    15.  
    16. MainWidget::~MainWidget()
    17. {
    18.  
    19. }
    To copy to clipboard, switch view to plain text mode 

    dummymodel.h
    Qt Code:
    1. #ifndef DUMMYMODEL_H
    2. #define DUMMYMODEL_H
    3.  
    4. #include <QAbstractListModel>
    5. #include <QStringList>
    6.  
    7. class DummyModel : public QAbstractListModel
    8. {
    9. Q_OBJECT
    10. public:
    11. enum DummyRoles {
    12. TitleRole=Qt::UserRole+1
    13. };
    14.  
    15. DummyModel(QObject* parent=NULL);
    16. ~DummyModel();
    17.  
    18. int rowCount(const QModelIndex &parent) const;
    19. QVariant data(const QModelIndex &index, int role) const;
    20. bool setData(const QModelIndex &index, const QVariant &value, int role);
    21.  
    22. private:
    23.  
    24. void fillData();
    25. QStringList m_data;
    26. };
    27.  
    28. #endif // DUMMYMODEL_H
    To copy to clipboard, switch view to plain text mode 

    dummymodel.cpp
    Qt Code:
    1. #include "dummymodel.h"
    2.  
    3. #include <QDateTime>
    4.  
    5. DummyModel::DummyModel(QObject *parent) : QAbstractListModel(parent)
    6. {
    7. m_data.clear();
    8. QHash<int, QByteArray> roles;
    9. roles[TitleRole]="title";
    10. setRoleNames(roles);
    11. fillData();
    12. }
    13.  
    14. DummyModel::~DummyModel()
    15. {
    16.  
    17. }
    18.  
    19. int DummyModel::rowCount(const QModelIndex &parent) const
    20. {
    21. return m_data.count();
    22. }
    23.  
    24. QVariant DummyModel::data(const QModelIndex &index, int role) const
    25. {
    26. qDebug("dummymodel::data");
    27. qDebug("Role: %d", role);
    28. if (!index.isValid()) return QVariant();
    29. if ((index.row()<0) || (index.row()>=m_data.count())) return QVariant();
    30. if (role==TitleRole)
    31. return m_data.at(index.row());
    32. return QVariant();
    33. }
    34.  
    35. void DummyModel::fillData()
    36. {
    37. qsrand(QDateTime::currentMSecsSinceEpoch());
    38. beginResetModel();
    39. m_data.clear();
    40. int num=1+qrand()%8;
    41. for (int i=0; i<num; i++)
    42. {
    43. m_data.append(QString("DummyText%1").arg(i+1));
    44. }
    45. endResetModel();
    46. }
    47.  
    48. bool DummyModel::setData(const QModelIndex &index, const QVariant &value, int role)
    49. {
    50. qDebug("SetData called");
    51. return true;
    52. }
    To copy to clipboard, switch view to plain text mode 

    and the qml file:
    main.qml
    Qt Code:
    1. import QtQuick 1.0
    2.  
    3.  
    4. Rectangle {
    5. id: base
    6. width: 500
    7. height: 360
    8. Repeater {
    9. model: dummyModel
    10. delegate: myDelegate
    11. }
    12.  
    13. Component {
    14. id: myDelegate
    15. Rectangle {
    16. x: 10
    17. y: index*35+10
    18. width: 200
    19. height: 30
    20. color: "yellow"
    21. TextEdit {
    22. text: title
    23. font.pointSize: 18
    24. }
    25. MouseArea {
    26. anchors.fill: parent
    27. onClicked: {
    28. console.log("Clicked index:",index);
    29. title="test"
    30. }
    31. }
    32. }
    33. }
    34. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Modify c++ model data from QML Repeater

    Try implementing flags() for your model and return ItemIsEditable.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Dec 2010
    Location
    Veszprém, Hungary
    Posts
    34
    Thanks
    2
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Modify c++ model data from QML Repeater

    Already tried.

    Qt Code:
    1. Qt::ItemFlags DummyModel::flags(const QModelIndex &index) const
    2. {
    3. qDebug("DummyModel::Flags");
    4. return Qt::ItemIsEditable;
    5. }
    To copy to clipboard, switch view to plain text mode 

    But unfortunately it doesn't help, but even the function is not called. (No qDebug output)

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Modify c++ model data from QML Repeater

    You have to return other flags as well.Like ItemIsEnabled. Make sure the signature fits and verify using QListView that your model is editable.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Dec 2010
    Location
    Veszprém, Hungary
    Posts
    34
    Thanks
    2
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Modify c++ model data from QML Repeater

    It is a good idea to test also with a QListView...

    I found that the behavior is a little different.
    From QML the flags function never called. In the data function the role is just the roles I have defined with setRoleNames call.

    If I use a form with QListView flags is called many times, and role is DisplayRole, and others, so I had to extend the model, to implement the displayrole also.

    But from QML, the answer is always: Cannot assign to read-only property 'title'

    Any other idea?

    Maybe I should use the solution with calling the slots...

  8. #8
    Join Date
    Sep 2009
    Posts
    8
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Modify c++ model data from QML Repeater

    I am also trying to use QAbstractItemModel::setData from QML, but it is not possible. QML model-view-controller connection with C++ Qt is build-in hardcoded suck, thats all.

Similar Threads

  1. Replies: 9
    Last Post: 14th February 2013, 20:39
  2. QMap model data
    By gyre in forum Newbie
    Replies: 3
    Last Post: 9th December 2007, 23:19
  3. Model - data
    By gyre in forum Newbie
    Replies: 1
    Last Post: 9th December 2007, 20:49
  4. Data model
    By steg90 in forum Qt Programming
    Replies: 3
    Last Post: 17th September 2007, 13:14
  5. Modify model data in QTreeView
    By YuriyRusinov in forum Qt Programming
    Replies: 6
    Last Post: 26th October 2006, 18:28

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.