Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Exposing QAbstractListModel to QML SegFault

Exposing QAbstractListModel to QML SegFault

Scheduled Pinned Locked Moved Solved QML and Qt Quick
8 Posts 3 Posters 2.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    blacky_i
    wrote on last edited by
    #1

    Hello everyone!

    I have strange behavior in Qt 5.2. I'm trying to expose QAbstractListModel to QML, but after adding items to it it shows SegFault.
    main.cpp

    qmlRegisterType<AttachmentsToSendModel>("VKModels",1,0,"AttachmentsToSendModel");
    

    AttachmentsToSendModel.cpp

    #include "attachmentstosendmodel.h"
    
    AttachmentsToSendModel::AttachmentsToSendModel(QObject *parent)
    {
        setParent(parent);
        roles=roleNames();
        beginInsertRows(QModelIndex(),rowCount(),rowCount());
        AttachmentToSendItem* itm = new AttachmentToSendItem(this);
        QQmlEngine::setObjectOwnership(itm, QQmlEngine::CppOwnership);
        itm->setSource("file:///home/nemo/Pictures/SK/NwC1iub1wog.jpg");
        itm->setType(static_cast<AttachmentToSendItem::FileType>(0));
        Items.append(itm);
        endInsertRows();
    
    }
    
    AttachmentsToSendModel::~AttachmentsToSendModel()
    {
        qDebug()<<"Killed";
    }
    
    void AttachmentsToSendModel::addAttachment(QString source, int Type)
    {
        qDebug()<<source;
     beginInsertRows(QModelIndex(),rowCount(),rowCount());
     AttachmentToSendItem* itm = new AttachmentToSendItem(this);
     QQmlEngine::setObjectOwnership(itm, QQmlEngine::CppOwnership);
     itm->setSource(source);
     itm->setType(static_cast<AttachmentToSendItem::FileType>(Type));
     Items.append(itm);
     endInsertRows();
    }
    
    
    QModelIndex AttachmentsToSendModel::index(int row, int column, const QModelIndex &parent) const
    {
    }
    
    int AttachmentsToSendModel::rowCount(const QModelIndex &parent) const
    {
        return Items.count();
    }
    
    QVariant AttachmentsToSendModel::data(const QModelIndex &index, int role) const
    {
        if(!index.isValid())
            return QVariant();
        if(index.row()>=Items.size())
            return QVariant();
        if(role==TYPE)
            return Items.at(index.row())->Type();
        if(role==SOURCE)
        {
            qDebug()<<Items.at(index.row())->Source();
    //        return Items.at(index.row())->Source();
        }
        if(role==URL)
            qDebug()<<Items.at(index.row())->Url();
        if(role==STATUS)
            qDebug()<<Items.at(index.row())->Status();
        if(role==PROGRESS)
            qDebug()<<Items.at(index.row())->progress();
        if(role==TOTAL)
            qDebug()<<Items.at(index.row())->total();
     //   const RecursingWallItem* Wi = Items.at(index.row());
    
        return QVariant();
    
    }
    
    //bool AttachmentsToSendModel::insertRows(int row, int count, const QModelIndex &parent)
    //{
    //}
    
    //bool AttachmentsToSendModel::removeRows(int row, int count, const QModelIndex &parent)
    //{
    //    beginRemoveRows(QModelIndex(),row,count);
    //    for(int i=0;i<count;i++)
    //    {
    //        Items.at(row+i)->deleteLater();
    //        Items.removeAt(row+i);
    //    }
    //    qDebug()<<"deleting Attach";
    //    endRemoveRows();
    
    //}
    
    QHash<int, QByteArray> AttachmentsToSendModel::roleNames() const
    {
        QHash<int, QByteArray> roles;
    
        roles[TYPE] = "type";
        roles[SOURCE] = "c_source";
        roles[STATUS]="c_status";
        roles[URL] = "url";
        roles[PROGRESS] = "progress";
        roles[TOTAL] = "total";
    
        return roles;
    
    
    }
    

    AttachmentsToSendItem.h

    #ifndef ATTACHMENTTOSENDITEM_H
    #define ATTACHMENTTOSENDITEM_H
    
    #include <QObject>
    #include <QDebug>
    
    class AttachmentToSendItem : public QObject
    {
        Q_OBJECT
    
    public:
        explicit AttachmentToSendItem(QObject* parent=0);
        AttachmentToSendItem(QString source, int type);
        ~AttachmentToSendItem();
        Q_ENUMS(FileType)
        Q_PROPERTY(QString Url READ Url WRITE setUrl NOTIFY UrlChanged)
        Q_PROPERTY(int progress READ progress WRITE setProgress NOTIFY progressChanged)
        Q_PROPERTY(int total READ total WRITE setTotal NOTIFY totalChanged)
        Q_PROPERTY(QString Source READ Source WRITE setSource NOTIFY SourceChanged)
        Q_PROPERTY(FileType Type READ Type WRITE setType NOTIFY TypeChanged)
        Q_PROPERTY(int Status READ Status WRITE setStatus NOTIFY StatusChanged)
        enum FileType {
            PHOTO,
            VIDEO,
            AUDIO,
            DOC,
            WALL
        };
        QString Url() const;
    
        int progress() const;
    
        int total() const;
    
        QString Source() const;
    
        FileType Type() const;
    
        int Status() const;
    
    signals:
    
        void UrlChanged(QString Url);
    
        void progressChanged(int progress);
    
        void totalChanged(int total);
    
        void SourceChanged(QString Source);
    
        void TypeChanged(FileType Type);
    
        void StatusChanged(int Status);
    
    public slots:
        void setUrl(QString Url);
        void setProgress(int progress);
    
        void setTotal(int total);
    
        void setSource(QString Source);
    
        void setType(FileType Type);
    
        void setStatus(int Status);
    
    private:
        QString m_Url="";
        int m_progress=0;
        int m_total;
        QString m_Source;
        FileType m_Type;
        int m_Status=2;
    };
    
    #endif // ATTACHMENTTOSENDITEM_H
    

    AttachmentToSendItem.cpp

    #include "attachmenttosenditem.h"
    
    
    AttachmentToSendItem::AttachmentToSendItem(QObject *parent)
    {
        setParent(parent);
    }
    
    AttachmentToSendItem::AttachmentToSendItem(QString source,int type)
    {
        setSource(source);
        setType(static_cast<FileType>(type));
    }
    
    AttachmentToSendItem::~AttachmentToSendItem()
    {
        qDebug()<<"Killed";
    }
    
    QString AttachmentToSendItem::Url() const
    {
        return m_Url;
    }
    
    int AttachmentToSendItem::progress() const
    {
        return m_progress;
    }
    
    int AttachmentToSendItem::total() const
    {
        return m_total;
    }
    
    QString AttachmentToSendItem::Source() const
    {
        return m_Source;
    }
    
    AttachmentToSendItem::FileType AttachmentToSendItem::Type() const
    {
        return m_Type;
    }
    
    int AttachmentToSendItem::Status() const
    {
        return m_Status;
    }
    
    void AttachmentToSendItem::setUrl(QString Url)
    {
        if (m_Url == Url)
            return;
        
        m_Url = Url;
        emit UrlChanged(Url);
    }
    
    void AttachmentToSendItem::setProgress(int progress)
    {
        if (m_progress == progress)
            return;
        
        m_progress = progress;
        emit progressChanged(progress);
    }
    
    void AttachmentToSendItem::setTotal(int total)
    {
        if (m_total == total)
            return;
        
        m_total = total;
        emit totalChanged(total);
    }
    
    void AttachmentToSendItem::setSource(QString Source)
    {
        if (m_Source == Source)
            return;
        
        m_Source = Source;
        emit SourceChanged(Source);
    }
    
    void AttachmentToSendItem::setType(AttachmentToSendItem::FileType Type)
    {
        if (m_Type == Type)
            return;
    
        m_Type = Type;
        emit TypeChanged(Type);
    }
    
    void AttachmentToSendItem::setStatus(int Status)
    {
        if (m_Status == Status)
            return;
        
        m_Status = Status;
        emit StatusChanged(Status);
    }
    

    .qml

    
    import QtQuick 2.0
    import Sailfish.Silica 1.0
    import QtMultimedia 5.0
    import VKModels 1.0
    import ".."
    import "../items"
    import QtDocGallery 5.0
    import org.nemomobile.thumbnailer 1.0
    
    
    Page{
        id:page
    
        property string headertitle;
        property int chat_id;
        property bool isMulti:false
        property string sobesed_photo;
        onStatusChanged: {
            if(status == PageStatus.Active)
                historyModel.isActive = true;
            else if(status == PageStatus.Activating)
                historyModel.isActive = true;
    
            historyModel.isActive = false;
        }
        Component.onCompleted: {
            historyModel.clear_Messages();
            globalSettings.companionId=chat_id;
            vkapi.messages_getHistory(chat_id,0,20,-1);
        }
        Component.onDestruction:
        {
            globalSettings.companionId=0;
        }
    
        Drawer{
            id:attachDrawer
            open:false
            dock:Dock.Bottom
            anchors.fill: parent
            PageHeader{
                id:name_info
                title:headertitle
                anchors {
                    leftMargin: 10
                }
            }
            SilicaListView {
                id: listView
                model: historyModel
                anchors.bottom: sendArea.top
                verticalLayoutDirection: ListView.BottomToTop
    
                PullDownMenu {
                    id:pulley
                    MenuItem {
                        text: "добавить прошлые записи"
                        onClicked:
                        {
                            vkapi.messages_getHistory(chat_id,listView.count,20,-1)
                        }
                    }
                }
    
                width: parent.width
                height: parent.height-name_info.height
                spacing: 30
                anchors {
                    top:name_info.bottom
                }
                clip:true
                delegate:MessageItem{
                    isOut:out
                    author: isMulti?first_name+ " "+last_name:""
                    fwdMsg: historyModel.getFwdMessage(id)
                    attachWallpost: historyModel.getFwdPost(id)
                }
    
            }
    
            Item{
                id:sendArea
                anchors.bottom: parent.bottom
                //            anchors.left:parent.left
                width: parent.width
                height: messageArea.height+attachmentstoSend.height+Theme.paddingSmall
    //! If model empty everything ok, but if it has items -> SegFault
                SilicaListView{
                    id:attachmentstoSend
                    width:parent.width
                    height: model.count>0?Theme.itemSizeMedium:0
                    anchors.bottom: messageArea.top
                    model:c_attachmentsModelToSend
                    orientation:Qt.Horizontal
                    spacing:5
                    delegate: Image{
                        width:Theme.itemSizeMedium
                        height:width
                        sourceSize: Qt.size(width,height)
                        source:"image://nemoThumbnail/"+c_source
                        IconButton{
                        icon.source: "image://theme/icon-s-clear-opaque-cross?"+Theme.highlightColor
                        anchors.centerIn: parent
                        //onClicked: c_attachmentsModelToSend.(index)
                        }
                        Rectangle{
                        color:"black"
                        visible: c_status>0
                        opacity: 0.5
                        }
                       BusyIndicator{
                           size: BusyIndicatorSize.Medium
                                   anchors.centerIn: parent
                                   running: c_status>0
    
                       }
                    }
                }
                IconButton {
                    id:skrepkaWizard
                    icon.source: "image://theme/icon-m-attach"
                    highlighted: false
                    anchors.bottom: messageArea.bottom
                    anchors.right:messageArea.left
                    anchors.bottomMargin: 25
                    onClicked: attachDrawer.open=true
                }
                TextArea {
                    id:messageArea
    
                    anchors.bottom: parent.bottom
                    anchors.right: sendButton.left
    
                    height:  Math.min(Theme.itemSizeExtraLarge,implicitHeight)//Math.max(page.height/5, Math.min(page.height/3,implicitHeight))
                    width:parent.width-sendButton.width- skrepkaWizard.width
                }
    
                IconButton {
                    id:sendButton
                    icon.source: "image://theme/icon-m-message"
                    highlighted: false
                    anchors.bottom: messageArea.bottom
                    //                anchors.left:messageArea.right
                    anchors.right:parent.right
                    anchors.bottomMargin: 25
    
                    onClicked: {
                        console.log(parent.width,sendButton.width,messageArea.width)
                        vkapi.messages_send(chat_id,messageArea.text)
                        messageArea.selectAll()
                        messageArea.text=""
                        highlighted=!highlighted
    
                        //       historyModel.clear_Messages()
                        //       vkapi.messages_getHistory(chat_id,false,20,0)
    
                    }
                }
            }
    
    
            MouseArea {
                enabled: attachDrawer.open
                anchors.fill: listView
                onClicked: attachDrawer.open = false
            }
    
    
            background:Loader{
                id:attachLoader
                anchors.fill: parent
                source:"../items/AttachComponent.qml"
    
            }
        }
    
    
        MessageModel{
            id:historyModel
            Component.onCompleted:
            {
                historyModel.DataProvider=c_dataProvider
                historyModel.userId=chat_id
            }
        }
        DocumentGalleryModel {
            id: galleryModel
            rootType: DocumentGallery.Image
            properties: [ "url", "title", "dateTaken" ]
            autoUpdate: true
            sortProperties: ["-dateTaken"]
        }
        ListModel{
            id:attachmentsModelToSend
        }
    
        Connections {
            target: attachLoader.item
            onS_items: {
                console.log(items)
                var types = ["photo","video","place","audio","doc","photoVK","videoVK"];
                for(var i=0;i<items.length;i++)
                {
                    console.log(items[i]);
                    var file = galleryModel.get(items[i].id).url;
                    console.log(file)
                    attachmentsModelToSend.append({"url":"image://nemoThumbnail/"+galleryModel.get(items[i].id).url,"type":types[items[i].type],"status":2})
                    c_attachmentsModelToSend.addAttachment(file,types[items[i].type])
                }
            }
        }
    }
    
    

    I understand that issue somehow has problem near ownership of QObject. But I can't find it.
    Please help.

    1 Reply Last reply
    0
    • p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by p3c0
      #2

      @blacky_i Since you have used qmlRegisterType you need to instantiate the type in QML.

      VKModels {
        id: vkModels
      }
      

      Is it done already? I found it missing in your code.
      http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html#exposing-c-data-models-to-qml

      157

      1 Reply Last reply
      0
      • B Offline
        B Offline
        blacky_i
        wrote on last edited by
        #3

        but VKModels is used as import in the beginning of QML...

        AttachmentsToSendModel is creating in here

        1 Reply Last reply
        0
        • p3c0P Offline
          p3c0P Offline
          p3c0
          Moderators
          wrote on last edited by p3c0
          #4

          @blacky_i import doesnot create it. It just makes aware about the type to the engine.
          See the example in the link posted earlier.

          157

          1 Reply Last reply
          0
          • B Offline
            B Offline
            blacky_i
            wrote on last edited by blacky_i
            #5

            Oh shoot! i posted wrong qml file! here I am creating AttachmentsToSendModel

            
            import QtQuick 2.0
            import Sailfish.Silica 1.0
            import QtMultimedia 5.0
            import VKModels 1.0
            import ".."
            import "../items"
            import QtDocGallery 5.0
            import org.nemomobile.thumbnailer 1.0
            
            
            Page{
                id:page
            
            
                signal addAttach(var src,var type);
                property string headertitle;
                property int chat_id;
                property bool isMulti:false
                property string sobesed_photo;
                onStatusChanged: {
                    if(status == PageStatus.Active)
                        historyModel.isActive = true;
                    else if(status == PageStatus.Activating)
                        historyModel.isActive = true;
            
                    historyModel.isActive = false;
                }
                Component.onCompleted: {
                    historyModel.clear_Messages();
                    globalSettings.companionId=chat_id;
                    vkapi.messages_getHistory(chat_id,0,20,-1);
                }
                Component.onDestruction:
                {
                    globalSettings.companionId=0;
                }
            
                Drawer{
                    id:attachDrawer
                    open:false
                    dock:Dock.Bottom
                    anchors.fill: parent
                    PageHeader{
                        id:name_info
                        title:headertitle
                        anchors {
                            leftMargin: 10
                        }
                    }
                    SilicaListView {
                        id: listView
                        model: historyModel
                        anchors.bottom: sendArea.top
                        verticalLayoutDirection: ListView.BottomToTop
            
                        PullDownMenu {
                            id:pulley
                            MenuItem {
                                text: "добавить прошлые записи"
                                onClicked:
                                {
                                    vkapi.messages_getHistory(chat_id,listView.count,20,-1)
                                }
                            }
                        }
            
                        width: parent.width
                        height: parent.height-name_info.height
                        spacing: 30
                        anchors {
                            top:name_info.bottom
                        }
                        clip:true
                        delegate:MessageItem{
                            isOut:out
                            author: isMulti?first_name+ " "+last_name:""
                            fwdMsg: historyModel.getFwdMessage(id)
                            attachWallpost: historyModel.getFwdPost(id)
                        }
            
                    }
            
                    Item{
                        id:sendArea
                        anchors.bottom: parent.bottom
                        //            anchors.left:parent.left
                        width: parent.width
                        height: messageArea.height+attachmentstoSend.height+Theme.paddingSmall
                        SilicaListView{
                            id:attachmentstoSend
                            width:parent.width
                            height: model.count>0?Theme.itemSizeMedium:0
                            anchors.bottom: messageArea.top
                            model:c_attachmentsModelToSend
                            orientation:Qt.Horizontal
                            spacing:5
                            delegate: Image{
                                width:Theme.itemSizeMedium
                                height:width
                                sourceSize: Qt.size(width,height)
                                source:"image://nemoThumbnail/"+c_source
                                IconButton{
                                icon.source: "image://theme/icon-s-clear-opaque-cross?"+Theme.highlightColor
                                anchors.centerIn: parent
                                //onClicked: c_attachmentsModelToSend.(index)
                                }
                                Rectangle{
                                color:"black"
                                visible: c_status>0
                                opacity: 0.5
                                }
                               BusyIndicator{
                                   size: BusyIndicatorSize.Medium
                                           anchors.centerIn: parent
                                           running: c_status>0
            
                               }
                            }
                        }
                        IconButton {
                            id:skrepkaWizard
                            icon.source: "image://theme/icon-m-attach"
                            highlighted: false
                            anchors.bottom: messageArea.bottom
                            anchors.right:messageArea.left
                            anchors.bottomMargin: 25
                            onClicked: attachDrawer.open=true
                        }
                        TextArea {
                            id:messageArea
            
                            anchors.bottom: parent.bottom
                            anchors.right: sendButton.left
            
                            height:  Math.min(Theme.itemSizeExtraLarge,implicitHeight)//Math.max(page.height/5, Math.min(page.height/3,implicitHeight))
                            width:parent.width-sendButton.width- skrepkaWizard.width
                        }
            
                        IconButton {
                            id:sendButton
                            icon.source: "image://theme/icon-m-message"
                            highlighted: false
                            anchors.bottom: messageArea.bottom
                            //                anchors.left:messageArea.right
                            anchors.right:parent.right
                            anchors.bottomMargin: 25
            
                            onClicked: {
                                console.log(parent.width,sendButton.width,messageArea.width)
                                vkapi.messages_send(chat_id,messageArea.text)
                                messageArea.selectAll()
                                messageArea.text=""
                                highlighted=!highlighted
            
                                //       historyModel.clear_Messages()
                                //       vkapi.messages_getHistory(chat_id,false,20,0)
            
                            }
                        }
                    }
            
            
                    MouseArea {
                        enabled: attachDrawer.open
                        anchors.fill: listView
                        onClicked: attachDrawer.open = false
                    }
            
            
                    background:Loader{
                        id:attachLoader
                        anchors.fill: parent
                        source:"../items/AttachComponent.qml"
            
                    }
                }
            
            
                MessageModel{
                    id:historyModel
                    Component.onCompleted:
                    {
                        historyModel.DataProvider=c_dataProvider
                        historyModel.userId=chat_id
                    }
                }
                DocumentGalleryModel {
                    id: galleryModel
                    rootType: DocumentGallery.Image
                    properties: [ "url", "title", "dateTaken" ]
                    autoUpdate: true
                    sortProperties: ["-dateTaken"]
                }
                AttachmentsToSendModel{
                id:c_attachmentsModelToSend
                }
            
            
            
                Connections {
                    target: attachLoader.item
                    onS_items: {
                        console.log(items)
                        var types = ["photo","video","place","audio","doc","photoVK","videoVK"];
                        for(var i=0;i<items.length;i++)
                        {
                            console.log(items[i]);
                            var file = galleryModel.get(items[i].id).url;
                            console.log(file)
                            c_attachmentsModelToSend.addAttachment(file,types[items[i].type])
                        }
                    }
                }
            }
            
            

            error still the same. If Items in model >0, then SegFault
            If in AttachmentToSendModel.cpp use List<AttachmentToSendItem> Items instead of List<AttachmentToSendItem*> Items as collection, After adding new item it deletes immediately and calling SegFault.

            1 Reply Last reply
            0
            • B Offline
              B Offline
              blacky_i
              wrote on last edited by
              #6

              Strange, but SegFault is gone.
              I removed realization of QModelIndex AttachmentsToSendModel::index(int row, int column, const QModelIndex &parent) and SegFault is gone.
              Any ideas why?

              1 Reply Last reply
              0
              • VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by
                #7

                this

                QModelIndex AttachmentsToSendModel::index(int row, int column, const QModelIndex &parent) const
                {
                }
                

                should not even compile, you need to return something...

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                1 Reply Last reply
                1
                • B Offline
                  B Offline
                  blacky_i
                  wrote on last edited by
                  #8

                  I understand my stupid errror. Problem solved.

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved