QAbstractListModel derive from interface: SIGFAULT



  • Hi,

    I have the following class:

    @
    class ListModel : public QAbstractListModel, public IDataModel
    {
    Q_OBJECT
    Q_INTERFACES(IDataModel)
    Q_PROPERTY(int count READ count NOTIFY countChanged)
    Q_PROPERTY(int currentIndex READ CurrentIndex NOTIFY currentIndexChanged)

    public:
    //model API
    enum Roles { ObjectRole = Qt::UserRole+1 };

    ListModel(QObject * aParent = 0);
    

    virtual ~ListModel();

    .................
    @

    This is the IDataModel interface:

    @
    class IDataModel
    {
    public:
    virtual ~IDataModel() {}

    virtual void AddItem(const ModelItemSharedPtr & aItem) = 0;
    
    virtual void Clear() = 0;
    
    virtual bool GetSelectedItem(ModelItemSharedPtr & aItem) = 0;
    
    virtual void SetPreviousItem() = 0;
    
    // To navigate through DataModel
    virtual void GoUp() = 0;
    virtual void GoDown() = 0;
    virtual void GoLeft() = 0;
    virtual void GoRight() = 0;
    

    };

    Q_DECLARE_INTERFACE(IDataModel, "IDataModel")
    @

    When I run this code I always get a sigfault in the ScriptValueEngine of QML... If I do not use the ListModel (my derived class) there is no problem.

    Does anyone have a suggestion, could this be a bug?



  • It depends on the implementation. Or is there a reason to think that the part you have shown is enough to find the problem?



    1. I'm not sure, but I think name ListModel conflicting with qml ListModel component name
    2. For QAbstractListModel inheritor you should define few virtual method, such as:
      rowCount, columnCount, data, etc.


  • Sorry for my late reply! I'll give some more information:

    I used my ListModel before (without deriving it from an interface) without any troubles. I use ListModel as follows:

    Header:
    @
    class ListModel : public QAbstractListModel, public IDataModel
    {
    Q_OBJECT
    Q_INTERFACES(IDataModel)
    Q_PROPERTY(int count READ count NOTIFY countChanged)
    Q_PROPERTY(int currentIndex READ CurrentIndex NOTIFY currentIndexChanged)

    public:
    //model API
    enum Roles { ObjectRole = Qt::UserRole+1 };

    ListModel(QObject * aParent = 0);
    

    virtual ~ListModel();

    int rowCount(const QModelIndex &parent;) const;
    QVariant data(const QModelIndex &index;, int role) const;
    
    virtual void AddItem(const ModelItemSharedPtr & aItem); // >>>>IMPLEMENTED FROM IDATAMODEL
    virtual void SetPreviousItem();  // >>>>IMPLEMENTED FROM IDATAMODEL
    virtual void Clear(); // >>>>IMPLEMENTED FROM IDATAMODEL 
    virtual bool GetSelectedItem(ModelItemSharedPtr & aItem); // >>>>IMPLEMENTED FROM IDATAMODEL
    
    virtual void GoUp(); // >>>>IMPLEMENTED FROM IDATAMODEL
    virtual void GoDown(); // >>>>IMPLEMENTED FROM IDATAMODEL
    virtual void GoLeft() {} // >>>>IMPLEMENTED FROM IDATAMODEL
    virtual void GoRight() {} // >>>>IMPLEMENTED FROM IDATAMODEL
    
    int CurrentIndex() const;
    void SetIndex(int aIndex);
    
    inline int count() const { return mItems.count(); }
    

    signals:
    void countChanged();
    void currentIndexChanged();

    private:
    int mCurrentIndex;
    int mPrevIndex;
    ItemList mItems;
    };
    @

    Source file:
    @
    #include "ListModel.h"

    ListModel::ListModel(QObject* aParent):
    QAbstractListModel(aParent),
    mCurrentIndex(START_POS), // Position in list starts from 0
    mPrevIndex(START_POS)
    {
    QHash<int, QByteArray> roles;
    roles[ObjectRole] = "object";
    setRoleNames(roles);
    }

    ListModel::~ListModel()
    {
    }

    bool ListModel::GetSelectedItem(ModelItemSharedPtr & aItem)
    {
    bool lFound = false;

    if (ValidIndex(mCurrentIndex))
    {
    aItem = mItems[mCurrentIndex];
    lFound = true;
    }

    return lFound;
    }

    void ListModel::AddItem(const ModelItemSharedPtr & aItem)
    {
    beginInsertRows(QModelIndex(), count(), count());
    mItems.push_back(aItem);
    endInsertRows();
    emit countChanged();
    }

    QVariant ListModel::data(const QModelIndex &index;, int role) const
    {
    if (index.row() < 0 || index.row() >= count())
    return QVariant();

    if (role == ObjectRole)
     return QVariant::fromValue((QObject*)(mItems.at(index.row()).data()));
    
    return QVariant();
    

    }

    int ListModel::rowCount(const QModelIndex &parent;) const
    {
    Q_UNUSED(parent);
    return count();
    }

    int ListModel::CurrentIndex() const
    {
    return mCurrentIndex;
    }

    void ListModel::GoUp()
    {
    }

    void ListModel::GoDown()
    {
    }

    void ListModel::Clear()
    {
    // Goto first element in list
    mItems.clear();
    GoFirst();
    reset();
    }
    @



  • Interface IDataModel:
    @

    #pragma once

    #include "ModelItem.h"

    class IDataModel
    {
    public:
    virtual ~IDataModel() {}

    virtual void AddItem(const ModelItemSharedPtr & aItem) = 0;
    
    virtual void Clear() = 0;
    
    virtual bool GetSelectedItem(ModelItemSharedPtr & aItem) = 0;
    
    virtual void SetPreviousItem() = 0;
    
    // To navigate through DataModel
    virtual void GoUp() = 0;
    virtual void GoDown() = 0;
    virtual void GoLeft() = 0;
    virtual void GoRight() = 0;
    

    };

    Q_DECLARE_INTERFACE(IDataModel, "mmi.IDataModel")
    @

    I map ListModel to a QML listview:

    @
    ListView {
    id: list
    highlight: Rectangle {color: "darkgrey"; radius: 5}
    y: 27
    spacing: 2
    width: parent.width
    height: 196

    Component {
    id: listDelegate
    Item {
    width: parent.width; height: listItem.height; x: 5

    Column {
     ListItem {
      id: listItem 
      text: modelData.text
      subtext: modelData.subtext
      item_enabled: modelData.item_enabled       
     }
    }
    

    }
    }

    delegate: listDelegate
    }
    @

    If I use this code (ListModel derived from IDataModel) the scriptengine of QML crashes! If I ONLY remove the interface there is no problem at all...



  • [quote author="Vass" date="1310546861"]1. I'm not sure, but I think name ListModel conflicting with qml ListModel component name 2. For QAbstractListModel inheritor you should define few virtual method, such as: rowCount, columnCount, data, etc.[/quote]

    I tried to change ListModel to ListDataModel but that didn't help. Those virtual methods you are talking about I have implemented..



  • I fixed the problem myself.

    When I mapped the ListModel to QML using setContextProperty I used a static cast to cast the IDataModel* to a QObject. This was wrong, now I use dynamic_cast and no more crash!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.